couchbase 3.8.1 → 3.9.0

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 (475) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/CMakeLists.txt +16 -1
  4. data/ext/cache/cpm/{CPM_0.42.0.cmake → CPM_0.43.1.cmake} +18 -2
  5. data/ext/cache/extconf_include.rb +6 -6
  6. data/ext/cache/mozilla-ca-bundle.crt +214 -155
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/couchbase/CMakeLists.txt +130 -21
  9. data/ext/couchbase/cmake/APKBUILD.in +25 -4
  10. data/ext/couchbase/cmake/Bundler.cmake +143 -34
  11. data/ext/couchbase/cmake/CPM.cmake +126 -12
  12. data/ext/couchbase/cmake/Cache.cmake +7 -1
  13. data/ext/couchbase/cmake/CompilerOptions.cmake +1 -1
  14. data/ext/couchbase/cmake/CompilerWarnings.cmake +17 -6
  15. data/ext/couchbase/cmake/GrpcProtobuf.cmake +481 -0
  16. data/ext/couchbase/cmake/OpenSSL.cmake +10 -3
  17. data/ext/couchbase/cmake/Packaging.cmake +519 -65
  18. data/ext/couchbase/cmake/Protostellar.cmake +250 -0
  19. data/ext/couchbase/cmake/Sanitizers.cmake +61 -50
  20. data/ext/couchbase/cmake/StaticAnalyzers.cmake +16 -5
  21. data/ext/couchbase/cmake/TestFramework.cmake +283 -0
  22. data/ext/couchbase/cmake/TestFrameworkAddTests.cmake +51 -0
  23. data/ext/couchbase/cmake/Testing.cmake +27 -9
  24. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +141 -8
  25. data/ext/couchbase/cmake/VersionInfo.cmake +50 -0
  26. data/ext/couchbase/cmake/build_config.hxx.in +2 -1
  27. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +101 -23
  28. data/ext/couchbase/cmake/couchbase_cxx_client_static-config.cmake.in +7 -0
  29. data/ext/couchbase/cmake/couchbase_cxx_client_static.pc.in +2 -0
  30. data/ext/couchbase/cmake/gRPC_Generate.cmake +58 -0
  31. data/ext/couchbase/cmake/protobuf_Generate.cmake +69 -0
  32. data/ext/couchbase/cmake/require-git-checkout.cmake +25 -0
  33. data/ext/couchbase/cmake/tarball_glob.txt +49 -0
  34. data/ext/couchbase/core/agent_group.cxx +0 -8
  35. data/ext/couchbase/core/agent_group.hxx +0 -4
  36. data/ext/couchbase/core/analytics_stream.cxx +314 -0
  37. data/ext/couchbase/core/analytics_stream.hxx +129 -0
  38. data/ext/couchbase/core/analytics_stream_component.cxx +245 -0
  39. data/ext/couchbase/core/analytics_stream_component.hxx +67 -0
  40. data/ext/couchbase/core/app_telemetry_meter.cxx +25 -3
  41. data/ext/couchbase/core/app_telemetry_meter.hxx +77 -0
  42. data/ext/couchbase/core/app_telemetry_reporter.cxx +7 -6
  43. data/ext/couchbase/core/bucket.cxx +381 -87
  44. data/ext/couchbase/core/bucket.hxx +105 -25
  45. data/ext/couchbase/core/bucket_unit_test_api.hxx +57 -0
  46. data/ext/couchbase/core/capella.hxx +91 -0
  47. data/ext/couchbase/core/cluster.cxx +1554 -398
  48. data/ext/couchbase/core/cluster.hxx +39 -8
  49. data/ext/couchbase/core/cluster_agent.cxx +0 -8
  50. data/ext/couchbase/core/cluster_agent.hxx +0 -4
  51. data/ext/couchbase/core/cluster_options.hxx +26 -3
  52. data/ext/couchbase/core/collections_component.cxx +39 -15
  53. data/ext/couchbase/core/config_profiles.cxx +1 -1
  54. data/ext/couchbase/core/crud_component.cxx +2 -2
  55. data/ext/couchbase/core/crud_options.hxx +34 -0
  56. data/ext/couchbase/core/crypto/cbcrypto.cc +18 -13
  57. data/ext/couchbase/core/document_id_redaction.hxx +81 -0
  58. data/ext/couchbase/core/error_context/base_error_context.hxx +7 -6
  59. data/ext/couchbase/core/error_context/key_value.cxx +25 -2
  60. data/ext/couchbase/core/error_context/key_value.hxx +60 -33
  61. data/ext/couchbase/core/error_context/key_value_error_context.hxx +16 -15
  62. data/ext/couchbase/core/error_context/search.hxx +5 -0
  63. data/ext/couchbase/core/error_context/search_json.hxx +3 -0
  64. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +19 -18
  65. data/ext/couchbase/core/error_context/view.hxx +5 -0
  66. data/ext/couchbase/core/free_form_http_request.cxx +237 -4
  67. data/ext/couchbase/core/free_form_http_request.hxx +41 -8
  68. data/ext/couchbase/core/http_component.cxx +300 -284
  69. data/ext/couchbase/core/http_component.hxx +0 -4
  70. data/ext/couchbase/core/impl/analytics.cxx +38 -5
  71. data/ext/couchbase/core/impl/analytics.hxx +34 -0
  72. data/ext/couchbase/core/impl/bootstrap_error.hxx +0 -3
  73. data/ext/couchbase/core/impl/collection.cxx +215 -202
  74. data/ext/couchbase/core/impl/collection_manager.cxx +1 -1
  75. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +45 -18
  76. data/ext/couchbase/core/impl/error.cxx +22 -2
  77. data/ext/couchbase/core/impl/internal_analytics_stream_result.hxx +111 -0
  78. data/ext/couchbase/core/impl/internal_query_stream_result.hxx +110 -0
  79. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +15 -7
  80. data/ext/couchbase/core/impl/key_value_error_category.cxx +6 -0
  81. data/ext/couchbase/core/impl/lookup_in_replica.cxx +10 -10
  82. data/ext/couchbase/core/impl/lookup_in_replica.hxx +4 -4
  83. data/ext/couchbase/core/impl/node_id.cxx +49 -13
  84. data/ext/couchbase/core/impl/observability_recorder.cxx +12 -2
  85. data/ext/couchbase/core/impl/observe_poll.cxx +63 -23
  86. data/ext/couchbase/core/impl/public_analytics_stream_result.cxx +372 -0
  87. data/ext/couchbase/core/impl/public_bucket.cxx +48 -2
  88. data/ext/couchbase/core/impl/public_cluster.cxx +325 -25
  89. data/ext/couchbase/core/impl/public_query_stream_result.cxx +380 -0
  90. data/ext/couchbase/core/impl/public_transaction_get_multi_replicas_from_preferred_server_group_result.cxx +42 -0
  91. data/ext/couchbase/core/impl/public_transaction_get_multi_result.cxx +42 -0
  92. data/ext/couchbase/core/impl/query.cxx +76 -7
  93. data/ext/couchbase/core/impl/query.hxx +36 -0
  94. data/ext/couchbase/core/impl/query_index_manager.cxx +54 -1
  95. data/ext/couchbase/core/impl/replica_utils.cxx +101 -0
  96. data/ext/couchbase/core/impl/replica_utils.hxx +64 -0
  97. data/ext/couchbase/core/impl/resolve_node_id.hxx +125 -0
  98. data/ext/couchbase/core/impl/scope.cxx +70 -0
  99. data/ext/couchbase/core/impl/search.cxx +31 -1
  100. data/ext/couchbase/core/impl/transactions.cxx +130 -0
  101. data/ext/couchbase/core/impl/wait_until_ready.cxx +439 -0
  102. data/ext/couchbase/core/impl/wait_until_ready.hxx +110 -0
  103. data/ext/couchbase/core/impl/with_bucket_config_or_timeout.hxx +180 -0
  104. data/ext/couchbase/core/impl/with_cancellation.hxx +11 -3
  105. data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +66 -0
  106. data/ext/couchbase/core/io/dns_client.cxx +122 -45
  107. data/ext/couchbase/core/io/dns_codec.hxx +21 -21
  108. data/ext/couchbase/core/io/dns_config.cxx +21 -6
  109. data/ext/couchbase/core/io/http_command.hxx +149 -121
  110. data/ext/couchbase/core/io/http_error.hxx +107 -0
  111. data/ext/couchbase/core/io/http_parser.cxx +4 -0
  112. data/ext/couchbase/core/io/http_session.cxx +606 -154
  113. data/ext/couchbase/core/io/http_session.hxx +147 -30
  114. data/ext/couchbase/core/io/http_session_manager.hxx +329 -382
  115. data/ext/couchbase/core/io/http_streaming_parser.cxx +4 -0
  116. data/ext/couchbase/core/io/http_streaming_response.cxx +328 -43
  117. data/ext/couchbase/core/io/http_streaming_response.hxx +37 -3
  118. data/ext/couchbase/core/io/mcbp_buffer_pool.hxx +122 -0
  119. data/ext/couchbase/core/io/mcbp_command.hxx +150 -51
  120. data/ext/couchbase/core/io/mcbp_command_id.hxx +45 -0
  121. data/ext/couchbase/core/io/mcbp_message.cxx +9 -1
  122. data/ext/couchbase/core/io/mcbp_message.hxx +19 -0
  123. data/ext/couchbase/core/io/mcbp_output_queue.hxx +150 -0
  124. data/ext/couchbase/core/io/mcbp_parser.cxx +24 -7
  125. data/ext/couchbase/core/io/mcbp_session.cxx +316 -317
  126. data/ext/couchbase/core/io/mcbp_session.hxx +27 -18
  127. data/ext/couchbase/core/io/opaque_ring_table.hxx +145 -0
  128. data/ext/couchbase/core/io/retry_orchestrator.hxx +6 -5
  129. data/ext/couchbase/core/io/stream_deadline.hxx +50 -0
  130. data/ext/couchbase/core/io/streams.cxx +275 -14
  131. data/ext/couchbase/core/io/streams.hxx +53 -0
  132. data/ext/couchbase/core/logger/logger.cxx +36 -0
  133. data/ext/couchbase/core/logger/logger.hxx +46 -6
  134. data/ext/couchbase/core/logger/redaction.hxx +503 -0
  135. data/ext/couchbase/core/management/eventing_status.hxx +10 -0
  136. data/ext/couchbase/core/management/eventing_status_json.hxx +4 -0
  137. data/ext/couchbase/core/mcbp/big_endian.cxx +1 -1
  138. data/ext/couchbase/core/mcbp/codec.cxx +27 -18
  139. data/ext/couchbase/core/mcbp/operation_queue.cxx +2 -2
  140. data/ext/couchbase/core/mcbp/packet.hxx +2 -2
  141. data/ext/couchbase/core/mcbp/queue_request.cxx +23 -6
  142. data/ext/couchbase/core/mcbp/queue_request.hxx +21 -0
  143. data/ext/couchbase/core/meta/features.hxx +13 -0
  144. data/ext/couchbase/core/meta/version.cxx +6 -3
  145. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -10
  146. data/ext/couchbase/core/metrics/meter_wrapper.cxx +63 -33
  147. data/ext/couchbase/core/metrics/meter_wrapper.hxx +55 -3
  148. data/ext/couchbase/core/operations/analytics_response_parsing.cxx +177 -0
  149. data/ext/couchbase/core/operations/analytics_response_parsing.hxx +55 -0
  150. data/ext/couchbase/core/operations/document_analytics.cxx +48 -130
  151. data/ext/couchbase/core/operations/document_analytics.hxx +14 -2
  152. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +15 -7
  153. data/ext/couchbase/core/operations/document_get_any_replica.hxx +19 -8
  154. data/ext/couchbase/core/operations/document_get_projected.cxx +1 -1
  155. data/ext/couchbase/core/{impl/get_replica.cxx → operations/document_get_replica.cxx} +21 -3
  156. data/ext/couchbase/core/{impl/get_replica.hxx → operations/document_get_replica.hxx} +31 -4
  157. data/ext/couchbase/core/operations/document_lookup_in.cxx +10 -10
  158. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +228 -198
  159. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +215 -217
  160. data/ext/couchbase/core/operations/document_query.cxx +108 -221
  161. data/ext/couchbase/core/operations/document_query.hxx +18 -4
  162. data/ext/couchbase/core/operations/document_search.cxx +52 -8
  163. data/ext/couchbase/core/operations/document_search.hxx +3 -0
  164. data/ext/couchbase/core/operations/document_view.cxx +3 -3
  165. data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +15 -8
  166. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +4 -0
  167. data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +11 -6
  168. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.cxx +3 -2
  169. data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +10 -5
  170. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +10 -5
  171. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +2 -1
  172. data/ext/couchbase/core/operations/management/analytics_index_create.cxx +33 -8
  173. data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +12 -7
  174. data/ext/couchbase/core/operations/management/analytics_index_get_all.cxx +3 -2
  175. data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +11 -6
  176. data/ext/couchbase/core/operations/management/analytics_link_create.cxx +3 -3
  177. data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +10 -4
  178. data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +6 -4
  179. data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +4 -3
  180. data/ext/couchbase/core/operations/management/analytics_link_replace.cxx +3 -3
  181. data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +1 -1
  182. data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
  183. data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
  184. data/ext/couchbase/core/operations/management/change_password.cxx +2 -0
  185. data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
  186. data/ext/couchbase/core/operations/management/error_utils.cxx +59 -5
  187. data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
  188. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
  189. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
  190. data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
  191. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
  192. data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
  193. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
  194. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
  195. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
  196. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
  197. data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
  198. data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
  199. data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
  200. data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
  201. data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
  202. data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
  203. data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
  204. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
  205. data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
  206. data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
  207. data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
  208. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
  209. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
  210. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
  211. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
  212. data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
  213. data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
  214. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
  215. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
  216. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
  217. data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
  218. data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
  219. data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
  220. data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
  221. data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
  222. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
  223. data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
  224. data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
  225. data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
  226. data/ext/couchbase/core/operations_fwd.hxx +3 -3
  227. data/ext/couchbase/core/origin.cxx +54 -26
  228. data/ext/couchbase/core/origin.hxx +12 -0
  229. data/ext/couchbase/core/orphan_reporter.cxx +2 -1
  230. data/ext/couchbase/core/platform/random.cc +7 -7
  231. data/ext/couchbase/core/protocol/client_request.cxx +2 -2
  232. data/ext/couchbase/core/protocol/client_request.hxx +38 -21
  233. data/ext/couchbase/core/protocol/client_response.cxx +11 -3
  234. data/ext/couchbase/core/protocol/client_response.hxx +27 -6
  235. data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
  236. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
  237. data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
  238. data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
  239. data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
  240. data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
  241. data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
  242. data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
  243. data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
  244. data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
  245. data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
  246. data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
  247. data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
  248. data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
  249. data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
  250. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
  251. data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
  252. data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
  253. data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
  254. data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
  255. data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
  256. data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
  257. data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
  258. data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
  259. data/ext/couchbase/core/protocol/datatype.hxx +118 -1
  260. data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
  261. data/ext/couchbase/core/protocol/magic.hxx +4 -0
  262. data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
  263. data/ext/couchbase/core/protocol/server_request.hxx +3 -1
  264. data/ext/couchbase/core/protocol/status.cxx +1 -1
  265. data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
  266. data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
  267. data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
  268. data/ext/couchbase/core/protostellar/component.cxx +2445 -0
  269. data/ext/couchbase/core/protostellar/component.hxx +391 -0
  270. data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
  271. data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
  272. data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
  273. data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
  274. data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
  275. data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
  276. data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
  277. data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
  278. data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
  279. data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
  280. data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
  281. data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
  282. data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
  283. data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
  284. data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
  285. data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
  286. data/ext/couchbase/core/query_stream.cxx +447 -0
  287. data/ext/couchbase/core/query_stream.hxx +141 -0
  288. data/ext/couchbase/core/query_stream_component.cxx +243 -0
  289. data/ext/couchbase/core/query_stream_component.hxx +68 -0
  290. data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
  291. data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
  292. data/ext/couchbase/core/response_handler.hxx +41 -4
  293. data/ext/couchbase/core/row_streamer.cxx +332 -46
  294. data/ext/couchbase/core/row_streamer.hxx +31 -1
  295. data/ext/couchbase/core/row_streamer_options.hxx +55 -0
  296. data/ext/couchbase/core/sasl/client.h +3 -0
  297. data/ext/couchbase/core/search_scoring.hxx +66 -0
  298. data/ext/couchbase/core/stream_error_details.hxx +69 -0
  299. data/ext/couchbase/core/timeout_defaults.hxx +0 -1
  300. data/ext/couchbase/core/topology/capabilities.hxx +6 -0
  301. data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
  302. data/ext/couchbase/core/topology/configuration.cxx +21 -6
  303. data/ext/couchbase/core/topology/configuration.hxx +29 -8
  304. data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
  305. data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
  306. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
  307. data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
  308. data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
  309. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +362 -241
  310. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +24 -3
  311. data/ext/couchbase/core/transactions/error_list.hxx +2 -2
  312. data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
  313. data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
  314. data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
  315. data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
  316. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
  317. data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
  318. data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
  319. data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
  320. data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
  321. data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
  322. data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
  323. data/ext/couchbase/core/transactions/transactions.cxx +3 -55
  324. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +194 -66
  325. data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
  326. data/ext/couchbase/core/transactions/utils.cxx +10 -0
  327. data/ext/couchbase/core/transactions/waitable_op_list.hxx +15 -4
  328. data/ext/couchbase/core/transactions.hxx +9 -9
  329. data/ext/couchbase/core/utils/byteswap.hxx +166 -9
  330. data/ext/couchbase/core/utils/connection_string.cxx +50 -85
  331. data/ext/couchbase/core/utils/connection_string.hxx +15 -0
  332. data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
  333. data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
  334. data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
  335. data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
  336. data/ext/couchbase/core/utils/movable_function.hxx +301 -52
  337. data/ext/couchbase/core/utils/name_codec.hxx +154 -11
  338. data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
  339. data/ext/couchbase/core/utils/url_codec.cxx +12 -51
  340. data/ext/couchbase/core/websocket_codec.cxx +3 -29
  341. data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
  342. data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
  343. data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
  344. data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
  345. data/ext/couchbase/couchbase/bucket.hxx +57 -0
  346. data/ext/couchbase/couchbase/cluster.hxx +216 -5
  347. data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
  348. data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
  349. data/ext/couchbase/couchbase/collection.hxx +234 -14
  350. data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
  351. data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
  352. data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
  353. data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
  354. data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
  355. data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
  356. data/ext/couchbase/couchbase/error.hxx +32 -0
  357. data/ext/couchbase/couchbase/error_codes.hxx +32 -0
  358. data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
  359. data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
  360. data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
  361. data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
  362. data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
  363. data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
  364. data/ext/couchbase/couchbase/get_result.hxx +1 -0
  365. data/ext/couchbase/couchbase/increment_options.hxx +1 -1
  366. data/ext/couchbase/couchbase/insert_options.hxx +1 -1
  367. data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
  368. data/ext/couchbase/couchbase/match_query.hxx +1 -1
  369. data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
  370. data/ext/couchbase/couchbase/network_options.hxx +1 -1
  371. data/ext/couchbase/couchbase/node_id.hxx +42 -14
  372. data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
  373. data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
  374. data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
  375. data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
  376. data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
  377. data/ext/couchbase/couchbase/query_options.hxx +23 -12
  378. data/ext/couchbase/couchbase/query_row.hxx +111 -0
  379. data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
  380. data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
  381. data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
  382. data/ext/couchbase/couchbase/replace_options.hxx +3 -3
  383. data/ext/couchbase/couchbase/result.hxx +14 -3
  384. data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
  385. data/ext/couchbase/couchbase/scope.hxx +85 -2
  386. data/ext/couchbase/couchbase/search_options.hxx +58 -8
  387. data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
  388. data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
  389. data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
  390. data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
  391. data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
  392. data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
  393. data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
  394. data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
  395. data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
  396. data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
  397. data/ext/couchbase/couchbase/transactions.hxx +27 -18
  398. data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
  399. data/ext/couchbase/couchbase/vector_query.hxx +1 -1
  400. data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
  401. data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
  402. data/ext/extconf.rb +15 -10
  403. data/ext/rcb_analytics.cxx +82 -102
  404. data/ext/rcb_backend.cxx +42 -36
  405. data/ext/rcb_backend.hxx +2 -0
  406. data/ext/rcb_buckets.cxx +47 -59
  407. data/ext/rcb_collections.cxx +42 -52
  408. data/ext/rcb_crud.cxx +345 -224
  409. data/ext/rcb_diagnostics.cxx +117 -27
  410. data/ext/rcb_exceptions.cxx +152 -99
  411. data/ext/rcb_exceptions.hxx +25 -0
  412. data/ext/rcb_extras.cxx +18 -19
  413. data/ext/rcb_hdr_histogram.cxx +19 -4
  414. data/ext/rcb_logger.cxx +202 -27
  415. data/ext/rcb_logger.hxx +12 -0
  416. data/ext/rcb_multi.cxx +40 -40
  417. data/ext/rcb_observability.cxx +7 -5
  418. data/ext/rcb_query.cxx +99 -142
  419. data/ext/rcb_range_scan.cxx +41 -35
  420. data/ext/rcb_search.cxx +98 -99
  421. data/ext/rcb_users.cxx +36 -56
  422. data/ext/rcb_utils.cxx +100 -37
  423. data/ext/rcb_utils.hxx +287 -33
  424. data/ext/rcb_version.cxx +1 -1
  425. data/ext/rcb_views.cxx +55 -51
  426. data/lib/active_support/cache/couchbase_store.rb +77 -12
  427. data/lib/couchbase/bucket.rb +20 -0
  428. data/lib/couchbase/cluster.rb +33 -14
  429. data/lib/couchbase/collection.rb +36 -1
  430. data/lib/couchbase/errors.rb +18 -0
  431. data/lib/couchbase/fork_hooks.rb +16 -7
  432. data/lib/couchbase/get_replica_strategy.rb +89 -0
  433. data/lib/couchbase/logger.rb +1 -1
  434. data/lib/couchbase/management/analytics_index_manager.rb +15 -15
  435. data/lib/couchbase/management/bucket_manager.rb +6 -6
  436. data/lib/couchbase/management/collection_manager.rb +6 -6
  437. data/lib/couchbase/management/query_index_manager.rb +7 -7
  438. data/lib/couchbase/management/search_index_manager.rb +13 -13
  439. data/lib/couchbase/management/user_manager.rb +10 -10
  440. data/lib/couchbase/management/view_index_manager.rb +5 -5
  441. data/lib/couchbase/options.rb +181 -44
  442. data/lib/couchbase/protostellar/bucket.rb +4 -0
  443. data/lib/couchbase/protostellar/cluster.rb +4 -0
  444. data/lib/couchbase/protostellar/collection.rb +4 -0
  445. data/lib/couchbase/protostellar/error_handling.rb +2 -1
  446. data/lib/couchbase/protostellar/request.rb +1 -0
  447. data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
  448. data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
  449. data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
  450. data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
  451. data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
  452. data/lib/couchbase/search_options.rb +95 -6
  453. data/lib/couchbase/version.rb +1 -1
  454. metadata +92 -33
  455. data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
  456. data/ext/couchbase/core/columnar/agent.hxx +0 -71
  457. data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
  458. data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
  459. data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
  460. data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
  461. data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
  462. data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
  463. data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
  464. data/ext/couchbase/core/columnar/error.hxx +0 -51
  465. data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
  466. data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
  467. data/ext/couchbase/core/columnar/management_component.cxx +0 -300
  468. data/ext/couchbase/core/columnar/management_component.hxx +0 -56
  469. data/ext/couchbase/core/columnar/query_component.cxx +0 -523
  470. data/ext/couchbase/core/columnar/query_component.hxx +0 -57
  471. data/ext/couchbase/core/columnar/query_options.hxx +0 -59
  472. data/ext/couchbase/core/columnar/query_result.cxx +0 -130
  473. data/ext/couchbase/core/columnar/query_result.hxx +0 -78
  474. data/ext/couchbase/core/io/config_tracker.cxx +0 -687
  475. data/ext/couchbase/core/io/config_tracker.hxx +0 -123
@@ -30,104 +30,101 @@ namespace couchbase::core::operations::management
30
30
  {
31
31
 
32
32
  auto
33
- bucket_create_request::encode_to(encoded_request_type& encoded,
34
- http_context& /* context */) const -> std::error_code
33
+ bucket_create_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
34
+ -> std::error_code
35
35
  {
36
36
  encoded.method = "POST";
37
37
  encoded.path = "/pools/default/buckets";
38
38
 
39
39
  encoded.headers["content-type"] = "application/x-www-form-urlencoded";
40
- encoded.body.append(fmt::format("name={}", utils::string_codec::form_encode(bucket.name)));
40
+
41
+ std::map<std::string, std::string> values{};
42
+ values["name"] = bucket.name;
41
43
  switch (bucket.bucket_type) {
42
44
  case couchbase::core::management::cluster::bucket_type::couchbase:
43
- encoded.body.append("&bucketType=couchbase");
45
+ values["bucketType"] = "couchbase";
44
46
  break;
45
47
  case couchbase::core::management::cluster::bucket_type::memcached:
46
- encoded.body.append("&bucketType=memcached");
48
+ values["bucketType"] = "memcached";
47
49
  break;
48
50
  case couchbase::core::management::cluster::bucket_type::ephemeral:
49
- encoded.body.append("&bucketType=ephemeral");
51
+ values["bucketType"] = "ephemeral";
50
52
  break;
51
53
  case couchbase::core::management::cluster::bucket_type::unknown:
52
54
  break;
53
55
  }
54
56
  if (bucket.ram_quota_mb == 0) {
55
- encoded.body.append(fmt::format(
56
- "&ramQuotaMB={}", 100)); // If not explicitly set, set to prior default value of 100
57
+ values["ramQuotaMB"] = "100"; // If not explicitly set, set to prior default value of 100
57
58
  } else {
58
- encoded.body.append(fmt::format("&ramQuotaMB={}", bucket.ram_quota_mb));
59
+ values["ramQuotaMB"] = std::to_string(bucket.ram_quota_mb);
59
60
  }
60
61
 
61
62
  if (bucket.bucket_type != couchbase::core::management::cluster::bucket_type::memcached &&
62
63
  bucket.num_replicas.has_value()) {
63
- encoded.body.append(fmt::format("&replicaNumber={}", bucket.num_replicas.value()));
64
+ values["replicaNumber"] = std::to_string(bucket.num_replicas.value());
64
65
  }
65
66
  if (bucket.max_expiry.has_value()) {
66
- encoded.body.append(fmt::format("&maxTTL={}", bucket.max_expiry.value()));
67
+ values["maxTTL"] = std::to_string(bucket.max_expiry.value());
67
68
  }
68
69
  if (bucket.bucket_type != couchbase::core::management::cluster::bucket_type::ephemeral &&
69
70
  bucket.replica_indexes.has_value()) {
70
- encoded.body.append(
71
- fmt::format("&replicaIndex={}", bucket.replica_indexes.value() ? "1" : "0"));
71
+ values["replicaIndex"] = bucket.replica_indexes.value() ? "1" : "0";
72
72
  }
73
73
  if (bucket.history_retention_collection_default.has_value()) {
74
- encoded.body.append(
75
- fmt::format("&historyRetentionCollectionDefault={}",
76
- bucket.history_retention_collection_default.value() ? "true" : "false"));
74
+ values["historyRetentionCollectionDefault"] =
75
+ bucket.history_retention_collection_default.value() ? "true" : "false";
77
76
  }
78
77
  if (bucket.history_retention_bytes.has_value()) {
79
- encoded.body.append(
80
- fmt::format("&historyRetentionBytes={}", bucket.history_retention_bytes.value()));
78
+ values["historyRetentionBytes"] = std::to_string(bucket.history_retention_bytes.value());
81
79
  }
82
80
  if (bucket.history_retention_duration.has_value()) {
83
- encoded.body.append(
84
- fmt::format("&historyRetentionSeconds={}", bucket.history_retention_duration.value()));
81
+ values["historyRetentionSeconds"] = std::to_string(bucket.history_retention_duration.value());
85
82
  }
86
83
  if (bucket.flush_enabled.has_value()) {
87
- encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
84
+ values["flushEnabled"] = bucket.flush_enabled.value() ? "1" : "0";
88
85
  }
89
86
  if (bucket.num_vbuckets.has_value()) {
90
- encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
87
+ values["numVBuckets"] = std::to_string(bucket.num_vbuckets.value());
91
88
  }
92
89
 
93
90
  switch (bucket.eviction_policy) {
94
91
  case couchbase::core::management::cluster::bucket_eviction_policy::full:
95
- encoded.body.append("&evictionPolicy=fullEviction");
92
+ values["evictionPolicy"] = "fullEviction";
96
93
  break;
97
94
  case couchbase::core::management::cluster::bucket_eviction_policy::value_only:
98
- encoded.body.append("&evictionPolicy=valueOnly");
95
+ values["evictionPolicy"] = "valueOnly";
99
96
  break;
100
97
  case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction:
101
- encoded.body.append("&evictionPolicy=noEviction");
98
+ values["evictionPolicy"] = "noEviction";
102
99
  break;
103
100
  case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used:
104
- encoded.body.append("&evictionPolicy=nruEviction");
101
+ values["evictionPolicy"] = "nruEviction";
105
102
  break;
106
103
  case couchbase::core::management::cluster::bucket_eviction_policy::unknown:
107
104
  break;
108
105
  }
109
106
  switch (bucket.compression_mode) {
110
107
  case couchbase::core::management::cluster::bucket_compression::off:
111
- encoded.body.append("&compressionMode=off");
108
+ values["compressionMode"] = "off";
112
109
  break;
113
110
  case couchbase::core::management::cluster::bucket_compression::active:
114
- encoded.body.append("&compressionMode=active");
111
+ values["compressionMode"] = "active";
115
112
  break;
116
113
  case couchbase::core::management::cluster::bucket_compression::passive:
117
- encoded.body.append("&compressionMode=passive");
114
+ values["compressionMode"] = "passive";
118
115
  break;
119
116
  case couchbase::core::management::cluster::bucket_compression::unknown:
120
117
  break;
121
118
  }
122
119
  switch (bucket.conflict_resolution_type) {
123
120
  case couchbase::core::management::cluster::bucket_conflict_resolution::timestamp:
124
- encoded.body.append("&conflictResolutionType=lww");
121
+ values["conflictResolutionType"] = "lww";
125
122
  break;
126
123
  case couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number:
127
- encoded.body.append("&conflictResolutionType=seqno");
124
+ values["conflictResolutionType"] = "seqno";
128
125
  break;
129
126
  case couchbase::core::management::cluster::bucket_conflict_resolution::custom:
130
- encoded.body.append("&conflictResolutionType=custom");
127
+ values["conflictResolutionType"] = "custom";
131
128
  break;
132
129
  case couchbase::core::management::cluster::bucket_conflict_resolution::unknown:
133
130
  break;
@@ -135,16 +132,16 @@ bucket_create_request::encode_to(encoded_request_type& encoded,
135
132
  if (bucket.minimum_durability_level.has_value()) {
136
133
  switch (bucket.minimum_durability_level.value()) {
137
134
  case durability_level::none:
138
- encoded.body.append("&durabilityMinLevel=none");
135
+ values["durabilityMinLevel"] = "none";
139
136
  break;
140
137
  case durability_level::majority:
141
- encoded.body.append("&durabilityMinLevel=majority");
138
+ values["durabilityMinLevel"] = "majority";
142
139
  break;
143
140
  case durability_level::majority_and_persist_to_active:
144
- encoded.body.append("&durabilityMinLevel=majorityAndPersistActive");
141
+ values["durabilityMinLevel"] = "majorityAndPersistActive";
145
142
  break;
146
143
  case durability_level::persist_to_majority:
147
- encoded.body.append("&durabilityMinLevel=persistToMajority");
144
+ values["durabilityMinLevel"] = "persistToMajority";
148
145
  break;
149
146
  }
150
147
  }
@@ -152,12 +149,14 @@ bucket_create_request::encode_to(encoded_request_type& encoded,
152
149
  case couchbase::core::management::cluster::bucket_storage_backend::unknown:
153
150
  break;
154
151
  case couchbase::core::management::cluster::bucket_storage_backend::couchstore:
155
- encoded.body.append("&storageBackend=couchstore");
152
+ values["storageBackend"] = "couchstore";
156
153
  break;
157
154
  case couchbase::core::management::cluster::bucket_storage_backend::magma:
158
- encoded.body.append("&storageBackend=magma");
155
+ values["storageBackend"] = "magma";
159
156
  break;
160
157
  }
158
+
159
+ encoded.body = utils::string_codec::v2::form_encode(values);
161
160
  return {};
162
161
  }
163
162
  auto
@@ -30,8 +30,8 @@
30
30
  namespace couchbase::core::operations::management
31
31
  {
32
32
  auto
33
- bucket_update_request::encode_to(encoded_request_type& encoded,
34
- http_context& /* context */) const -> std::error_code
33
+ bucket_update_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
34
+ -> std::error_code
35
35
  {
36
36
  encoded.method = "POST";
37
37
  encoded.path =
@@ -39,65 +39,61 @@ bucket_update_request::encode_to(encoded_request_type& encoded,
39
39
 
40
40
  encoded.headers["content-type"] = "application/x-www-form-urlencoded";
41
41
 
42
+ std::map<std::string, std::string> values{};
42
43
  if (bucket.ram_quota_mb > 0) {
43
- encoded.body.append(fmt::format("&ramQuotaMB={}", bucket.ram_quota_mb));
44
+ values["ramQuotaMB"] = std::to_string(bucket.ram_quota_mb);
44
45
  }
45
46
  if (bucket.num_replicas.has_value()) {
46
- encoded.body.append(fmt::format("&replicaNumber={}", bucket.num_replicas.value()));
47
+ values["replicaNumber"] = std::to_string(bucket.num_replicas.value());
47
48
  }
48
-
49
49
  if (bucket.max_expiry.has_value()) {
50
- encoded.body.append(fmt::format("&maxTTL={}", bucket.max_expiry.value()));
50
+ values["maxTTL"] = std::to_string(bucket.max_expiry.value());
51
51
  }
52
52
  if (bucket.history_retention_collection_default.has_value()) {
53
- encoded.body.append(
54
- fmt::format("&historyRetentionCollectionDefault={}",
55
- bucket.history_retention_collection_default.value() ? "true" : "false"));
53
+ values["historyRetentionCollectionDefault"] =
54
+ bucket.history_retention_collection_default.value() ? "true" : "false";
56
55
  }
57
56
  if (bucket.history_retention_bytes.has_value()) {
58
- encoded.body.append(
59
- fmt::format("&historyRetentionBytes={}", bucket.history_retention_bytes.value()));
57
+ values["historyRetentionBytes"] = std::to_string(bucket.history_retention_bytes.value());
60
58
  }
61
59
  if (bucket.history_retention_duration.has_value()) {
62
- encoded.body.append(
63
- fmt::format("&historyRetentionSeconds={}", bucket.history_retention_duration.value()));
60
+ values["historyRetentionSeconds"] = std::to_string(bucket.history_retention_duration.value());
64
61
  }
65
62
  if (bucket.replica_indexes.has_value()) {
66
- encoded.body.append(
67
- fmt::format("&replicaIndex={}", bucket.replica_indexes.value() ? "1" : "0"));
63
+ values["replicaIndex"] = bucket.replica_indexes.value() ? "1" : "0";
68
64
  }
69
65
  if (bucket.flush_enabled.has_value()) {
70
- encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
66
+ values["flushEnabled"] = bucket.flush_enabled.value() ? "1" : "0";
71
67
  }
72
68
  if (bucket.num_vbuckets.has_value()) {
73
- encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
69
+ values["numVBuckets"] = std::to_string(bucket.num_vbuckets.value());
74
70
  }
75
71
 
76
72
  switch (bucket.eviction_policy) {
77
73
  case couchbase::core::management::cluster::bucket_eviction_policy::full:
78
- encoded.body.append("&evictionPolicy=fullEviction");
74
+ values["evictionPolicy"] = "fullEviction";
79
75
  break;
80
76
  case couchbase::core::management::cluster::bucket_eviction_policy::value_only:
81
- encoded.body.append("&evictionPolicy=valueOnly");
77
+ values["evictionPolicy"] = "valueOnly";
82
78
  break;
83
79
  case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction:
84
- encoded.body.append("&evictionPolicy=noEviction");
80
+ values["evictionPolicy"] = "noEviction";
85
81
  break;
86
82
  case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used:
87
- encoded.body.append("&evictionPolicy=nruEviction");
83
+ values["evictionPolicy"] = "nruEviction";
88
84
  break;
89
85
  case couchbase::core::management::cluster::bucket_eviction_policy::unknown:
90
86
  break;
91
87
  }
92
88
  switch (bucket.compression_mode) {
93
89
  case couchbase::core::management::cluster::bucket_compression::off:
94
- encoded.body.append("&compressionMode=off");
90
+ values["compressionMode"] = "off";
95
91
  break;
96
92
  case couchbase::core::management::cluster::bucket_compression::active:
97
- encoded.body.append("&compressionMode=active");
93
+ values["compressionMode"] = "active";
98
94
  break;
99
95
  case couchbase::core::management::cluster::bucket_compression::passive:
100
- encoded.body.append("&compressionMode=passive");
96
+ values["compressionMode"] = "passive";
101
97
  break;
102
98
  case couchbase::core::management::cluster::bucket_compression::unknown:
103
99
  break;
@@ -105,19 +101,21 @@ bucket_update_request::encode_to(encoded_request_type& encoded,
105
101
  if (bucket.minimum_durability_level) {
106
102
  switch (bucket.minimum_durability_level.value()) {
107
103
  case durability_level::none:
108
- encoded.body.append("&durabilityMinLevel=none");
104
+ values["durabilityMinLevel"] = "none";
109
105
  break;
110
106
  case durability_level::majority:
111
- encoded.body.append("&durabilityMinLevel=majority");
107
+ values["durabilityMinLevel"] = "majority";
112
108
  break;
113
109
  case durability_level::majority_and_persist_to_active:
114
- encoded.body.append("&durabilityMinLevel=majorityAndPersistActive");
110
+ values["durabilityMinLevel"] = "majorityAndPersistActive";
115
111
  break;
116
112
  case durability_level::persist_to_majority:
117
- encoded.body.append("&durabilityMinLevel=persistToMajority");
113
+ values["durabilityMinLevel"] = "persistToMajority";
118
114
  break;
119
115
  }
120
116
  }
117
+
118
+ encoded.body = utils::string_codec::v2::form_encode(values);
121
119
  return {};
122
120
  }
123
121
 
@@ -49,6 +49,8 @@ change_password_request::make_response(error_context::http&& ctx,
49
49
  if (encoded.body.data().find("Not allowed on this version of cluster") !=
50
50
  std::string::npos) {
51
51
  response.ctx.ec = errc::common::feature_not_available;
52
+ } else {
53
+ response.ctx.ec = errc::common::invalid_argument;
52
54
  }
53
55
  break;
54
56
  default:
@@ -47,7 +47,11 @@ collection_drop_request::make_response(error_context::http&& ctx,
47
47
  if (!response.ctx.ec) {
48
48
  switch (const auto& body = encoded.body.data(); encoded.status_code) {
49
49
  case 400:
50
- response.ctx.ec = errc::common::unsupported_operation;
50
+ if (body.find("Not allowed on this version of cluster") != std::string_view::npos) {
51
+ response.ctx.ec = errc::common::unsupported_operation;
52
+ } else {
53
+ response.ctx.ec = errc::common::invalid_argument;
54
+ }
51
55
  break;
52
56
  case 404: {
53
57
  const auto collection_prefix_pos = body.find("Collection with name ");
@@ -28,6 +28,10 @@ auto
28
28
  extract_common_error_code(std::uint32_t status_code, const std::string& response_body)
29
29
  -> std::error_code
30
30
  {
31
+ // RFC-58: a 400 that reaches this fallback is invalid_argument.
32
+ if (status_code == 400) {
33
+ return errc::common::invalid_argument;
34
+ }
31
35
  if (status_code == 429) {
32
36
  if (response_body.find("Limit(s) exceeded") != std::string::npos) {
33
37
  return errc::common::rate_limited;
@@ -59,6 +63,7 @@ extract_common_query_error_code(std::uint64_t code, const std::string& message)
59
63
 
60
64
  case 13014: /* ICode: E_DATASTORE_INSUFFICIENT_CREDENTIALS, IKey:
61
65
  "datastore.couchbase.insufficient_credentials" */
66
+ case 2120: /* ICode: E_ADMIN_AUTH, IKey: "admin.clustering.authorize" */
62
67
  return errc::common::authentication_failure;
63
68
 
64
69
  case 5000:
@@ -73,15 +78,26 @@ extract_common_query_error_code(std::uint64_t code, const std::string& message)
73
78
  break;
74
79
  }
75
80
 
81
+ // RFC-58 maps these ranges whatever the HTTP status, so a 400 carrying one is not
82
+ // invalid_argument.
83
+ if (code >= 5000 && code < 6000) {
84
+ return errc::common::internal_server_failure;
85
+ }
86
+ if (code >= 10000 && code < 11000) {
87
+ return errc::common::authentication_failure;
88
+ }
76
89
  return {};
77
90
  }
78
91
 
79
92
  auto
80
- extract_eventing_error_code(const tao::json::value& response)
93
+ extract_eventing_error_code(const tao::json::value& response, std::uint32_t status_code)
81
94
  -> std::pair<std::error_code, eventing_problem>
82
95
  {
96
+ // RFC-58: a 400 that names no specific problem is invalid_argument.
97
+ const std::error_code unmatched_400 =
98
+ status_code == 400 ? errc::common::invalid_argument : std::error_code{};
83
99
  if (!response.is_object()) {
84
- return {};
100
+ return { unmatched_400, {} };
85
101
  }
86
102
  if (const auto& name = response.find("name"); name != nullptr && name->is_string()) {
87
103
  std::string description;
@@ -131,9 +147,9 @@ extract_eventing_error_code(const tao::json::value& response)
131
147
  if (problem.name == "ERR_INVALID_CONFIG" || problem.name == "ERR_INTER_FUNCTION_RECURSION") {
132
148
  return { errc::common::invalid_argument, problem };
133
149
  }
134
- return { errc::common::internal_server_failure, problem };
150
+ return { unmatched_400 ? unmatched_400 : errc::common::internal_server_failure, problem };
135
151
  }
136
- return {};
152
+ return { unmatched_400, {} };
137
153
  }
138
154
 
139
155
  auto
@@ -215,6 +231,31 @@ translate_query_error_code(std::uint64_t error, const std::string& message, std:
215
231
  return extract_common_query_error_code(error, message);
216
232
  }
217
233
 
234
+ auto
235
+ extract_query_error_code(std::uint32_t status_code, const std::string& response_body)
236
+ -> std::error_code
237
+ {
238
+ tao::json::value payload{};
239
+ try {
240
+ payload = utils::json::parse(response_body);
241
+ } catch (const tao::pegtl::parse_error&) {
242
+ return extract_common_error_code(status_code, response_body);
243
+ }
244
+ if (const auto* errors = payload.is_object() ? payload.find("errors") : nullptr;
245
+ errors != nullptr && errors->is_array() && !errors->get_array().empty()) {
246
+ const auto& first = errors->get_array().front();
247
+ if (const auto* code = first.is_object() ? first.find("code") : nullptr;
248
+ code != nullptr && code->is_integer()) {
249
+ if (auto ec = translate_query_error_code(code->as<std::uint64_t>(),
250
+ first.optional<std::string>("msg").value_or(""));
251
+ ec) {
252
+ return ec.value();
253
+ }
254
+ }
255
+ }
256
+ return extract_common_error_code(status_code, response_body);
257
+ }
258
+
218
259
  auto
219
260
  translate_analytics_error_code(std::uint64_t error, const std::string& /* message */)
220
261
  -> std::optional<std::error_code>
@@ -229,6 +270,13 @@ translate_analytics_error_code(std::uint64_t error, const std::string& /* messag
229
270
  case 24006: /* Link [string] does not exist | Link [string] does not exist */
230
271
  return errc::analytics::link_not_found;
231
272
 
273
+ case 24000: /* RFC-58: ParsingFailure */
274
+ return errc::common::parsing_failure;
275
+
276
+ case 23000: /* RFC-58: TemporaryFailure */
277
+ case 23003: /* RFC-58: TemporaryFailure */
278
+ return errc::common::temporary_failure;
279
+
232
280
  case 23007: /* Job queue is full with [string] jobs */
233
281
  return errc::analytics::job_queue_full;
234
282
 
@@ -262,9 +310,15 @@ translate_analytics_error_code(std::uint64_t error, const std::string& /* messag
262
310
  if (error >= 24000 && error < 25000) {
263
311
  return errc::analytics::compilation_failure;
264
312
  }
313
+ if (error >= 20000 && error < 21000) {
314
+ return errc::common::authentication_failure;
315
+ }
316
+ if (error >= 25000 && error < 26000) {
317
+ return errc::common::internal_server_failure;
318
+ }
265
319
  break;
266
320
  }
267
- return errc::common::internal_server_failure;
321
+ return {};
268
322
  }
269
323
 
270
324
  auto
@@ -23,7 +23,10 @@
23
23
 
24
24
  #include <tao/json/forward.hpp>
25
25
 
26
+ #include <cstdint>
26
27
  #include <optional>
28
+ #include <string>
29
+ #include <system_error>
27
30
 
28
31
  namespace couchbase::core::operations::management
29
32
  {
@@ -35,16 +38,41 @@ std::optional<std::error_code>
35
38
  extract_common_query_error_code(std::uint64_t code, const std::string& message);
36
39
 
37
40
  std::pair<std::error_code, eventing_problem>
38
- extract_eventing_error_code(const tao::json::value& response);
41
+ extract_eventing_error_code(const tao::json::value& response, std::uint32_t status_code);
39
42
 
40
43
  std::optional<std::error_code>
41
44
  translate_query_error_code(std::uint64_t error,
42
45
  const std::string& message,
43
46
  std::uint64_t reason = 0);
44
47
 
48
+ /**
49
+ * RFC-58: the first query error code in the body decides, as for a query statement. Only a code
50
+ * without a mapping of its own, or a body without one, falls back on the HTTP status.
51
+ */
52
+ [[nodiscard]] std::error_code
53
+ extract_query_error_code(std::uint32_t status_code, const std::string& response_body);
54
+
45
55
  std::optional<std::error_code>
46
56
  translate_analytics_error_code(std::uint64_t error, const std::string& message);
47
57
 
58
+ /**
59
+ * RFC-58: the first analytics error code decides, through translate_analytics_error_code(). Only a
60
+ * code without a mapping of its own falls back on the HTTP status.
61
+ */
62
+ template<typename Problems>
63
+ [[nodiscard]] auto
64
+ extract_analytics_error_code(std::uint32_t status_code,
65
+ const Problems& errors,
66
+ const std::string& response_body) -> std::error_code
67
+ {
68
+ if (!errors.empty()) {
69
+ if (auto ec = translate_analytics_error_code(errors.front().code, errors.front().message); ec) {
70
+ return ec.value();
71
+ }
72
+ }
73
+ return extract_common_error_code(status_code, response_body);
74
+ }
75
+
48
76
  std::optional<std::error_code>
49
77
  translate_search_error_code(std::uint32_t status_code, const std::string& response_body);
50
78
 
@@ -30,7 +30,8 @@ eventing_deploy_function_request::encode_to(encoded_request_type& encoded,
30
30
  http_context& /* context */) const -> std::error_code
31
31
  {
32
32
  encoded.method = "POST";
33
- encoded.path = fmt::format("/api/v1/functions/{}/deploy", name);
33
+ encoded.path =
34
+ fmt::format("/api/v1/functions/{}/deploy", utils::string_codec::v2::path_escape(name));
34
35
  if (bucket_name.has_value() && scope_name.has_value()) {
35
36
  encoded.path += fmt::format("?bucket={}&scope={}",
36
37
  utils::string_codec::v2::path_escape(bucket_name.value()),
@@ -47,6 +48,9 @@ eventing_deploy_function_request::make_response(error_context::http&& ctx,
47
48
  eventing_deploy_function_response response{ std::move(ctx) };
48
49
  if (!response.ctx.ec) {
49
50
  if (encoded.body.data().empty()) {
51
+ if (encoded.status_code == 400) {
52
+ response.ctx.ec = errc::common::invalid_argument;
53
+ }
50
54
  return response;
51
55
  }
52
56
  tao::json::value payload{};
@@ -56,10 +60,12 @@ eventing_deploy_function_request::make_response(error_context::http&& ctx,
56
60
  response.ctx.ec = errc::common::parsing_failure;
57
61
  return response;
58
62
  }
59
- auto [ec, problem] = extract_eventing_error_code(payload);
63
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
60
64
  if (ec) {
61
65
  response.ctx.ec = ec;
62
- response.error.emplace(problem);
66
+ if (!problem.name.empty()) {
67
+ response.error.emplace(problem);
68
+ }
63
69
  }
64
70
  }
65
71
  return response;
@@ -30,7 +30,7 @@ eventing_drop_function_request::encode_to(encoded_request_type& encoded,
30
30
  http_context& /* context */) const -> std::error_code
31
31
  {
32
32
  encoded.method = "DELETE";
33
- encoded.path = fmt::format("/api/v1/functions/{}", name);
33
+ encoded.path = fmt::format("/api/v1/functions/{}", utils::string_codec::v2::path_escape(name));
34
34
  if (bucket_name.has_value() && scope_name.has_value()) {
35
35
  encoded.path += fmt::format("?bucket={}&scope={}",
36
36
  utils::string_codec::v2::path_escape(bucket_name.value()),
@@ -47,6 +47,9 @@ eventing_drop_function_request::make_response(error_context::http&& ctx,
47
47
  eventing_drop_function_response response{ std::move(ctx) };
48
48
  if (!response.ctx.ec) {
49
49
  if (encoded.body.data().empty()) {
50
+ if (encoded.status_code == 400) {
51
+ response.ctx.ec = errc::common::invalid_argument;
52
+ }
50
53
  return response;
51
54
  }
52
55
  tao::json::value payload{};
@@ -56,10 +59,12 @@ eventing_drop_function_request::make_response(error_context::http&& ctx,
56
59
  response.ctx.ec = errc::common::parsing_failure;
57
60
  return response;
58
61
  }
59
- auto [ec, problem] = extract_eventing_error_code(payload);
62
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
60
63
  if (ec) {
61
64
  response.ctx.ec = ec;
62
- response.error.emplace(problem);
65
+ if (!problem.name.empty()) {
66
+ response.error.emplace(problem);
67
+ }
63
68
  return response;
64
69
  }
65
70
  }
@@ -48,10 +48,12 @@ eventing_get_all_functions_request::make_response(error_context::http&& ctx,
48
48
  response.ctx.ec = errc::common::parsing_failure;
49
49
  return response;
50
50
  }
51
- auto [ec, problem] = extract_eventing_error_code(payload);
51
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
52
52
  if (ec) {
53
53
  response.ctx.ec = ec;
54
- response.error.emplace(problem);
54
+ if (!problem.name.empty()) {
55
+ response.error.emplace(problem);
56
+ }
55
57
  return response;
56
58
  }
57
59
  if (!payload.is_array()) {
@@ -31,7 +31,7 @@ eventing_get_function_request::encode_to(encoded_request_type& encoded,
31
31
  http_context& /* context */) const -> std::error_code
32
32
  {
33
33
  encoded.method = "GET";
34
- encoded.path = fmt::format("/api/v1/functions/{}", name);
34
+ encoded.path = fmt::format("/api/v1/functions/{}", utils::string_codec::v2::path_escape(name));
35
35
  if (bucket_name.has_value() && scope_name.has_value()) {
36
36
  encoded.path += fmt::format("?bucket={}&scope={}",
37
37
  utils::string_codec::v2::path_escape(bucket_name.value()),
@@ -54,10 +54,12 @@ eventing_get_function_request::make_response(error_context::http&& ctx,
54
54
  response.ctx.ec = errc::common::parsing_failure;
55
55
  return response;
56
56
  }
57
- auto [ec, problem] = extract_eventing_error_code(payload);
57
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
58
58
  if (ec) {
59
59
  response.ctx.ec = ec;
60
- response.error.emplace(problem);
60
+ if (!problem.name.empty()) {
61
+ response.error.emplace(problem);
62
+ }
61
63
  return response;
62
64
  }
63
65
  response.function = payload.as<couchbase::core::management::eventing::function>();
@@ -48,10 +48,12 @@ eventing_get_status_request::make_response(error_context::http&& ctx,
48
48
  response.ctx.ec = errc::common::parsing_failure;
49
49
  return response;
50
50
  }
51
- auto [ec, problem] = extract_eventing_error_code(payload);
51
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
52
52
  if (ec) {
53
53
  response.ctx.ec = ec;
54
- response.error.emplace(problem);
54
+ if (!problem.name.empty()) {
55
+ response.error.emplace(problem);
56
+ }
55
57
  return response;
56
58
  }
57
59
  response.status = payload.as<core::management::eventing::status>();
@@ -31,7 +31,8 @@ eventing_pause_function_request::encode_to(encoded_request_type& encoded,
31
31
  http_context& /* context */) const -> std::error_code
32
32
  {
33
33
  encoded.method = "POST";
34
- encoded.path = fmt::format("/api/v1/functions/{}/pause", name);
34
+ encoded.path =
35
+ fmt::format("/api/v1/functions/{}/pause", utils::string_codec::v2::path_escape(name));
35
36
  if (bucket_name.has_value() && scope_name.has_value()) {
36
37
  encoded.path += fmt::format("?bucket={}&scope={}",
37
38
  utils::string_codec::v2::path_escape(bucket_name.value()),
@@ -48,6 +49,9 @@ eventing_pause_function_request::make_response(error_context::http&& ctx,
48
49
  eventing_pause_function_response response{ std::move(ctx) };
49
50
  if (!response.ctx.ec) {
50
51
  if (encoded.body.data().empty()) {
52
+ if (encoded.status_code == 400) {
53
+ response.ctx.ec = errc::common::invalid_argument;
54
+ }
51
55
  return response;
52
56
  }
53
57
  tao::json::value payload{};
@@ -57,10 +61,12 @@ eventing_pause_function_request::make_response(error_context::http&& ctx,
57
61
  response.ctx.ec = errc::common::parsing_failure;
58
62
  return response;
59
63
  }
60
- auto [ec, problem] = extract_eventing_error_code(payload);
64
+ auto [ec, problem] = extract_eventing_error_code(payload, encoded.status_code);
61
65
  if (ec) {
62
66
  response.ctx.ec = ec;
63
- response.error.emplace(problem);
67
+ if (!problem.name.empty()) {
68
+ response.error.emplace(problem);
69
+ }
64
70
  }
65
71
  }
66
72
  return response;