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
@@ -1,523 +0,0 @@
1
- /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2024. Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #include "query_component.hxx"
19
-
20
- #include "backoff_calculator.hxx"
21
- #include "core/free_form_http_request.hxx"
22
- #include "core/http_component.hxx"
23
- #include "core/logger/logger.hxx"
24
- #include "core/pending_operation_connection_info.hxx"
25
- #include "core/platform/uuid.h"
26
- #include "core/row_streamer.hxx"
27
- #include "core/service_type.hxx"
28
- #include "core/utils/json.hxx"
29
- #include "error.hxx"
30
- #include "error_codes.hxx"
31
- #include "query_result.hxx"
32
- #include "retry_info.hxx"
33
-
34
- #include <asio/io_context.hpp>
35
- #include <asio/steady_timer.hpp>
36
- #include <gsl/util>
37
- #include <spdlog/fmt/bundled/chrono.h>
38
- #include <spdlog/fmt/bundled/core.h>
39
- #include <tao/json/value.hpp>
40
- #include <tl/expected.hpp>
41
-
42
- #include <cstdint>
43
- #include <memory>
44
- #include <mutex>
45
- #include <string>
46
- #include <system_error>
47
- #include <utility>
48
- #include <vector>
49
-
50
- namespace couchbase::core::columnar
51
- {
52
- class pending_query_operation
53
- : public std::enable_shared_from_this<pending_query_operation>
54
- , public pending_operation
55
- {
56
- public:
57
- pending_query_operation(const query_options& options,
58
- asio::io_context& io,
59
- http_component& http,
60
- std::chrono::milliseconds default_timeout)
61
- : client_context_id_{ uuid::to_string(uuid::random()) }
62
- , timeout_{ options.timeout.value_or(default_timeout) }
63
- , payload_(build_query_payload(options))
64
- , http_req_{ build_query_request(options) }
65
- , io_{ io }
66
- , deadline_{ io_ }
67
- , retry_timer_{ io_ }
68
- , http_{ http }
69
- {
70
- }
71
-
72
- auto invoke_callback(query_result res, error err)
73
- {
74
- const std::scoped_lock lock{ callback_mutex_ };
75
- if (auto cb = std::move(callback_); cb) {
76
- cb(std::move(res), std::move(err));
77
- }
78
- }
79
-
80
- auto dispatch() -> error
81
- {
82
- auto op = http_.do_http_request(
83
- http_req_, [self = shared_from_this()](auto resp, error_union err) mutable {
84
- std::shared_ptr<pending_operation> op;
85
- {
86
- const std::scoped_lock lock{ self->pending_op_mutex_ };
87
- std::swap(op, self->pending_op_);
88
- }
89
- if (!std::holds_alternative<std::monostate>(err)) {
90
- if (std::holds_alternative<impl::bootstrap_error>(err)) {
91
- auto bootstrap_error = std::get<impl::bootstrap_error>(err);
92
- auto message = fmt::format(
93
- "Failed to execute the HTTP request for the query due to a bootstrap error. "
94
- "See logs for further details. bootstrap_error.message={}",
95
- bootstrap_error.error_message);
96
- self->invoke_callback({}, { maybe_convert_error_code(bootstrap_error.ec), message });
97
- } else {
98
- auto ec = maybe_convert_error_code(std::get<std::error_code>(err));
99
- if (ec == errc::timeout) {
100
- return self->trigger_timeout();
101
- }
102
- self->invoke_callback({}, { ec, "Failed to execute the HTTP request for the query" });
103
- }
104
- return;
105
- }
106
- // op can be null if the pending_query_operation was cancelled.
107
- if (op) {
108
- auto op_info = std::dynamic_pointer_cast<pending_operation_connection_info>(op);
109
- self->retry_info_.last_dispatched_from = op_info->dispatched_from();
110
- self->retry_info_.last_dispatched_to = op_info->dispatched_to();
111
- self->retry_info_.last_dispatched_to_host = op_info->dispatched_to_host();
112
- }
113
- auto streamer = std::make_shared<row_streamer>(self->io_, resp.body(), "/results/^");
114
- return streamer->start(
115
- [self, streamer, resp = std::move(resp)](const auto& metadata_header, auto ec) mutable {
116
- if (ec) {
117
- self->invoke_callback({}, { maybe_convert_error_code(ec) });
118
- return;
119
- }
120
- auto error_parse_res =
121
- self->parse_error(resp.status_code(), utils::json::parse(metadata_header));
122
-
123
- if (error_parse_res.retriable) {
124
- self->retry_info_.last_error = error_parse_res.err;
125
- return self->maybe_retry();
126
- }
127
-
128
- if (error_parse_res.err) {
129
- self->invoke_callback({}, { error_parse_res.err });
130
- return;
131
- }
132
- self->invoke_callback(query_result{ std::move(*streamer) }, {});
133
- });
134
- });
135
-
136
- if (op.has_value()) {
137
- const std::scoped_lock lock{ pending_op_mutex_ };
138
- pending_op_ = op.value();
139
- return {};
140
- }
141
- retry_timer_.cancel();
142
- deadline_.cancel();
143
- error return_error{};
144
- #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
145
- if (std::holds_alternative<impl::bootstrap_error>(op.error())) {
146
- auto bootstrap_error = std::get<impl::bootstrap_error>(op.error());
147
- auto message =
148
- fmt::format("Failed to create the HTTP pending operation due to a bootstrap error. "
149
- "See logs for further details. bootstrap_error.message={}",
150
- bootstrap_error.error_message);
151
- return_error.ec = bootstrap_error.ec;
152
- return_error.message = message;
153
- } else {
154
- return_error.ec = std::get<std::error_code>(op.error());
155
- return_error.message = "Failed to create the HTTP pending operation.";
156
- }
157
- #else
158
- return_error.ec = op.error();
159
- #endif
160
- invoke_callback({}, return_error);
161
- return return_error;
162
- }
163
-
164
- auto start(query_callback&& callback) -> error
165
- {
166
- callback_ = std::move(callback);
167
-
168
- deadline_.expires_after(timeout_);
169
- deadline_.async_wait([self = shared_from_this()](auto ec) {
170
- if (ec == asio::error::operation_aborted) {
171
- return;
172
- }
173
- CB_LOG_DEBUG(R"(Columnar Query request timed out: retry_attempts={})",
174
- self->retry_info_.retry_attempts);
175
- self->trigger_timeout();
176
- });
177
-
178
- return dispatch();
179
- }
180
-
181
- void cancel() override
182
- {
183
- cancelled_ = true;
184
- retry_timer_.cancel();
185
- deadline_.cancel();
186
- std::shared_ptr<pending_operation> op;
187
- {
188
- const std::scoped_lock lock{ pending_op_mutex_ };
189
- std::swap(op, pending_op_);
190
- }
191
- if (op) {
192
- op->cancel();
193
- }
194
- // This will only call the callback if it has not already been called (e.g. in the case of a
195
- // timeout).
196
- invoke_callback({},
197
- { couchbase::core::columnar::client_errc::canceled,
198
- "The query operation was canceled by the caller." });
199
- }
200
-
201
- private:
202
- void update_http_request_timeout()
203
- {
204
- http_req_.timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
205
- deadline_.expiry() - std::chrono::steady_clock::now());
206
- const auto server_timeout = http_req_.timeout + std::chrono::seconds(5);
207
- payload_["timeout"] = fmt::format("{}ms", server_timeout.count());
208
- http_req_.body = couchbase::core::utils::json::generate(payload_);
209
- }
210
-
211
- void maybe_retry()
212
- {
213
- if (cancelled_) {
214
- return;
215
- }
216
- auto backoff = backoff_calculator_(retry_info_.retry_attempts);
217
- if (std::chrono::steady_clock::now() + backoff >= deadline_.expiry()) {
218
- // Retrying will exceed the deadline, time out immediately instead.
219
- return trigger_timeout();
220
- }
221
- retry_timer_.expires_after(backoff);
222
- retry_timer_.async_wait([self = shared_from_this()](auto ec) {
223
- if (ec == asio::error::operation_aborted) {
224
- return;
225
- }
226
- self->retry_info_.retry_attempts++;
227
- self->http_req_.internal.undesired_endpoint = self->retry_info_.last_dispatched_to;
228
- self->update_http_request_timeout();
229
- CB_LOG_DEBUG(
230
- "Retrying Query: client_context_id={}, http_timeout={}, retry_attempt={}, errors={}",
231
- self->client_context_id_,
232
- self->http_req_.timeout,
233
- self->retry_info_.retry_attempts,
234
- utils::json::generate(self->retry_info_.last_error.ctx["errors"]));
235
- auto err = self->dispatch();
236
- if (err) {
237
- self->invoke_callback({}, std::move(err));
238
- }
239
- });
240
- }
241
-
242
- void trigger_timeout()
243
- {
244
- error err{ errc::timeout };
245
- enhance_error(err);
246
- invoke_callback({}, err);
247
- cancel();
248
- }
249
-
250
- auto build_query_payload(const query_options& options) -> tao::json::value
251
- {
252
- tao::json::value payload{ { "statement", options.statement },
253
- { "client_context_id", client_context_id_ } };
254
- if (options.database_name.has_value() && options.scope_name.has_value()) {
255
- payload["query_context"] =
256
- fmt::format("default:`{}`.`{}`", options.database_name.value(), options.scope_name.value());
257
- }
258
- if (!options.positional_parameters.empty()) {
259
- std::vector<tao::json::value> params_json;
260
- params_json.reserve(options.positional_parameters.size());
261
- for (const auto& val : options.positional_parameters) {
262
- params_json.emplace_back(utils::json::parse(val));
263
- }
264
- payload["args"] = std::move(params_json);
265
- }
266
- for (const auto& [name, val] : options.named_parameters) {
267
- std::string key = name;
268
- if (key[0] != '$') {
269
- key.insert(key.begin(), '$');
270
- }
271
- payload[key] = utils::json::parse(val);
272
- }
273
- if (options.read_only.has_value()) {
274
- payload["readonly"] = options.read_only.value();
275
- }
276
- if (options.scan_consistency.has_value()) {
277
- switch (options.scan_consistency.value()) {
278
- case query_scan_consistency::not_bounded:
279
- payload["scan_consistency"] = "not_bounded";
280
- break;
281
- case query_scan_consistency::request_plus:
282
- payload["scan_consistency"] = "request_plus";
283
- break;
284
- }
285
- }
286
-
287
- const std::chrono::milliseconds server_timeout = timeout_ + std::chrono::seconds(5);
288
- payload["timeout"] = fmt::format("{}ms", server_timeout.count());
289
-
290
- for (const auto& [key, val] : options.raw) {
291
- payload[key] = utils::json::parse(val);
292
- }
293
-
294
- return payload;
295
- }
296
-
297
- auto build_query_request(const query_options& options) -> http_request
298
- {
299
- http_request req{ service_type::analytics, "POST" };
300
- req.path = "/api/v1/request";
301
- req.body = utils::json::generate(payload_);
302
- req.timeout = timeout_;
303
-
304
- req.client_context_id = client_context_id_;
305
- req.headers["connection"] = "keep-alive";
306
- req.headers["content-type"] = "application/json";
307
- if (options.priority.has_value() && options.priority.value()) {
308
- req.headers["analytics-priority"] = "-1";
309
- }
310
- if (options.read_only.has_value()) {
311
- req.is_read_only = options.read_only.value();
312
- }
313
- CB_LOG_DEBUG("QUERY REQUEST: client_context_id={}, body={}.", client_context_id_, req.body);
314
- return req;
315
- }
316
-
317
- struct error_parse_result {
318
- error err{};
319
- bool retriable{ false };
320
- };
321
-
322
- void enhance_error(error& err)
323
- {
324
- err.ctx["retry_attempts"] = retry_info_.retry_attempts;
325
- err.ctx["last_dispatched_to"] = retry_info_.last_dispatched_to;
326
- err.ctx["last_dispatched_from"] = retry_info_.last_dispatched_from;
327
-
328
- // When reporting a timeout that is a result of an operation being retried, the last set of
329
- // retryable errors should be listed.
330
- if (err.ec == errc::timeout && retry_info_.last_error) {
331
- if (const auto* e = retry_info_.last_error.ctx.find("errors"); e != nullptr) {
332
- err.ctx["last_errors"] = e->get_array();
333
- }
334
- }
335
- }
336
-
337
- auto parse_error(const std::uint32_t& http_status_code,
338
- const tao::json::value& metadata_header) -> error_parse_result
339
- {
340
- const auto* errors_json = metadata_header.find("errors");
341
- if (errors_json == nullptr) {
342
- return {};
343
- }
344
- CB_LOG_DEBUG("QUERY ERROR (client_context_id={}): {}.",
345
- client_context_id_,
346
- utils::json::generate(errors_json));
347
- if (!errors_json->is_array()) {
348
- return { { errc::generic,
349
- "Could not parse errors from server response - expected JSON array" } };
350
- }
351
- if (errors_json->get_array().empty()) {
352
- return {};
353
- }
354
-
355
- error_parse_result res;
356
- res.retriable = true;
357
- res.err.ctx["http_status"] = std::to_string(http_status_code);
358
- res.err.ctx["errors"] = std::vector<tao::json::value>{};
359
- enhance_error(res.err);
360
-
361
- if (http_status_code == 401) {
362
- res.err.ec = errc::invalid_credential;
363
- } else {
364
- res.err.ec = errc::query_error;
365
- }
366
-
367
- std::int32_t first_error_code{ 0 };
368
- std::string first_error_msg{};
369
-
370
- std::int32_t first_non_retr_error_code{ 0 };
371
- std::string first_non_retr_error_msg{};
372
-
373
- for (auto error_json : errors_json->get_array()) {
374
- bool retr{ false }; // An error is assumed to not be retriable if the field is missing
375
- {
376
- auto* r = error_json.find("retriable");
377
- if (r != nullptr) {
378
- if (!r->is_boolean()) {
379
- return {
380
- { errc::generic,
381
- "Could not parse error from server response - 'retriable' was not boolean" }
382
- };
383
- }
384
- retr = r->get_boolean();
385
- }
386
- }
387
-
388
- // Operation is retriable iff all errors are retriable
389
- res.retriable = res.retriable && retr;
390
-
391
- std::string msg{};
392
- {
393
- auto* m = error_json.find("msg");
394
- if (m == nullptr) {
395
- return { { errc::generic,
396
- "Could not parse error from server response - could not find 'msg' field" } };
397
- }
398
- if (!m->is_string()) {
399
- return { { errc::generic,
400
- "Could not parse error from server response - 'msg' field was not string" } };
401
- }
402
- msg = m->get_string();
403
- }
404
-
405
- std::int32_t code{};
406
- {
407
- auto* c = error_json.find("code");
408
- if (c == nullptr) {
409
- return { { errc::generic,
410
- "Could not parse error from server response - could not find 'code' field" } };
411
- }
412
- if (!(c->is_unsigned() || c->is_signed())) {
413
- return {
414
- { errc::generic,
415
- "Could not parse error from server response - 'code' field was not an integer" }
416
- };
417
- }
418
- code = c->is_signed() ? gsl::narrow_cast<std::int32_t>(c->get_signed())
419
- : gsl::narrow_cast<std::int32_t>(c->get_unsigned());
420
- }
421
-
422
- tao::json::value error = {
423
- { "code", code },
424
- { "msg", msg },
425
- };
426
- res.err.ctx["errors"].get_array().emplace_back(std::move(error));
427
-
428
- if (first_error_code == 0) {
429
- first_error_code = code;
430
- first_error_msg = msg;
431
- }
432
- if (!retr && first_non_retr_error_code == 0) {
433
- first_non_retr_error_code = code;
434
- first_non_retr_error_msg = msg;
435
- }
436
-
437
- switch (code) {
438
- case 20000:
439
- res.err.ec = errc::invalid_credential;
440
- break;
441
- case 21002:
442
- res.err.ec = errc::timeout;
443
- break;
444
- default:
445
- break;
446
- }
447
- }
448
-
449
- if (res.err.ec == errc::query_error) {
450
- // If any of the errors is not retriable, report the first non-retriable code/message in the
451
- // error properties
452
- if (first_non_retr_error_code != 0) {
453
- res.err.properties =
454
- query_error_properties{ first_non_retr_error_code, first_non_retr_error_msg };
455
- } else {
456
- res.err.properties = query_error_properties{ first_error_code, first_error_msg };
457
- }
458
- }
459
-
460
- return res;
461
- }
462
-
463
- std::string client_context_id_;
464
- std::chrono::milliseconds timeout_;
465
- tao::json::value payload_;
466
- http_request http_req_;
467
- asio::io_context& io_;
468
- asio::steady_timer deadline_;
469
- asio::steady_timer retry_timer_;
470
- http_component& http_;
471
- query_callback callback_{};
472
- std::mutex callback_mutex_{};
473
- std::shared_ptr<pending_operation> pending_op_{};
474
- std::mutex pending_op_mutex_{};
475
- std::atomic_bool cancelled_{ false };
476
- backoff_calculator backoff_calculator_{ default_backoff_calculator };
477
- retry_info retry_info_{};
478
- };
479
-
480
- class query_component_impl : public std::enable_shared_from_this<query_component_impl>
481
- {
482
- public:
483
- query_component_impl(asio::io_context& io,
484
- http_component http,
485
- std::chrono::milliseconds default_timeout)
486
- : io_{ io }
487
- , http_{ std::move(http) }
488
- , default_timeout_{ default_timeout }
489
- {
490
- }
491
-
492
- auto execute_query(const query_options& options, query_callback&& callback)
493
- -> tl::expected<std::shared_ptr<pending_operation>, error>
494
- {
495
- auto op = std::make_shared<pending_query_operation>(options, io_, http_, default_timeout_);
496
- auto err = op->start(std::move(callback));
497
- if (err) {
498
- return tl::unexpected<error>(err);
499
- }
500
- return op;
501
- }
502
-
503
- private:
504
- asio::io_context& io_;
505
- http_component http_;
506
- std::chrono::milliseconds default_timeout_;
507
- };
508
-
509
- query_component::query_component(asio::io_context& io,
510
- core::http_component http,
511
- std::chrono::milliseconds default_timeout)
512
- : impl_{ std::make_shared<query_component_impl>(io, std::move(http), default_timeout) }
513
- {
514
- }
515
-
516
- auto
517
- query_component::execute_query(const query_options& options, query_callback&& callback)
518
- -> tl::expected<std::shared_ptr<pending_operation>, error>
519
- {
520
- return impl_->execute_query(options, std::move(callback));
521
- }
522
-
523
- } // namespace couchbase::core::columnar
@@ -1,57 +0,0 @@
1
- /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2024. Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #pragma once
19
-
20
- #include "core/impl/bootstrap_error.hxx"
21
- #include "core/pending_operation.hxx"
22
- #include "error.hxx"
23
- #include "query_options.hxx"
24
-
25
- #include <chrono>
26
- #include <memory>
27
-
28
- #include <tl/expected.hpp>
29
-
30
- namespace asio
31
- {
32
- class io_context;
33
- } // namespace asio
34
-
35
- namespace couchbase::core
36
- {
37
- class http_component;
38
-
39
- namespace columnar
40
- {
41
- class query_component_impl;
42
-
43
- class query_component
44
- {
45
- public:
46
- query_component(asio::io_context& io,
47
- http_component http,
48
- std::chrono::milliseconds default_timeout);
49
-
50
- auto execute_query(const query_options& options, query_callback&& callback)
51
- -> tl::expected<std::shared_ptr<pending_operation>, error>;
52
-
53
- private:
54
- std::shared_ptr<query_component_impl> impl_;
55
- };
56
- } // namespace columnar
57
- } // namespace couchbase::core
@@ -1,59 +0,0 @@
1
- /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
- /*
3
- * Copyright 2024. Couchbase, Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License");
6
- * you may not use this file except in compliance with the License.
7
- * You may obtain a copy of the License at
8
- *
9
- * http://www.apache.org/licenses/LICENSE-2.0
10
- *
11
- * Unless required by applicable law or agreed to in writing, software
12
- * distributed under the License is distributed on an "AS IS" BASIS,
13
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- * See the License for the specific language governing permissions and
15
- * limitations under the License.
16
- */
17
-
18
- #pragma once
19
-
20
- #include "error.hxx"
21
- #include "query_result.hxx"
22
-
23
- #include "core/json_string.hxx"
24
- #include "core/utils/movable_function.hxx"
25
-
26
- #include <chrono>
27
- #include <map>
28
- #include <optional>
29
- #include <string>
30
- #include <system_error>
31
- #include <vector>
32
-
33
- namespace couchbase::core::columnar
34
- {
35
- enum class query_scan_consistency : std::uint8_t {
36
- not_bounded,
37
- request_plus,
38
- };
39
-
40
- struct query_options {
41
- // Required
42
- std::string statement;
43
-
44
- // Optional - should be set if query is at scope-level
45
- std::optional<std::string> database_name{};
46
- std::optional<std::string> scope_name{};
47
-
48
- // Optional - not sent on the wire if unset
49
- std::optional<bool> priority{};
50
- std::vector<couchbase::core::json_string> positional_parameters{};
51
- std::map<std::string, couchbase::core::json_string> named_parameters{};
52
- std::optional<bool> read_only{};
53
- std::optional<query_scan_consistency> scan_consistency{};
54
- std::map<std::string, couchbase::core::json_string> raw{};
55
- std::optional<std::chrono::milliseconds> timeout{};
56
- };
57
-
58
- using query_callback = utils::movable_function<void(query_result result, error err)>;
59
- } // namespace couchbase::core::columnar