couchbase 3.8.2 → 3.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  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 +121 -55
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/couchbase/CMakeLists.txt +136 -23
  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 +82 -7
  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 +1551 -397
  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 +229 -42
  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 +1 -2
  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 +309 -301
  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 +151 -21
  131. data/ext/couchbase/core/io/streams.hxx +48 -1
  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/change_password.cxx +2 -0
  183. data/ext/couchbase/core/operations/management/collection_drop.cxx +5 -1
  184. data/ext/couchbase/core/operations/management/error_utils.cxx +60 -6
  185. data/ext/couchbase/core/operations/management/error_utils.hxx +29 -1
  186. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +9 -3
  187. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +8 -3
  188. data/ext/couchbase/core/operations/management/eventing_get_all_functions.cxx +4 -2
  189. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +5 -3
  190. data/ext/couchbase/core/operations/management/eventing_get_status.cxx +4 -2
  191. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +9 -3
  192. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +9 -3
  193. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +9 -3
  194. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +9 -3
  195. data/ext/couchbase/core/operations/management/group_drop.cxx +3 -1
  196. data/ext/couchbase/core/operations/management/group_get.cxx +3 -1
  197. data/ext/couchbase/core/operations/management/group_upsert.cxx +11 -8
  198. data/ext/couchbase/core/operations/management/query_index_build.cxx +5 -2
  199. data/ext/couchbase/core/operations/management/query_index_create.cxx +9 -3
  200. data/ext/couchbase/core/operations/management/query_index_drop.cxx +11 -4
  201. data/ext/couchbase/core/operations/management/query_index_get_all.cxx +1 -1
  202. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.cxx +1 -1
  203. data/ext/couchbase/core/operations/management/scope_drop.cxx +5 -1
  204. data/ext/couchbase/core/operations/management/scope_get_all.cxx +6 -1
  205. data/ext/couchbase/core/operations/management/search_get_stats.cxx +10 -0
  206. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +3 -2
  207. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +4 -3
  208. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +4 -3
  209. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +4 -3
  210. data/ext/couchbase/core/operations/management/search_index_drop.cxx +2 -2
  211. data/ext/couchbase/core/operations/management/search_index_get.cxx +2 -2
  212. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +3 -2
  213. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +3 -1
  214. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +2 -2
  215. data/ext/couchbase/core/operations/management/user_drop.cxx +3 -1
  216. data/ext/couchbase/core/operations/management/user_get.cxx +3 -1
  217. data/ext/couchbase/core/operations/management/user_upsert.cxx +12 -9
  218. data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
  219. data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
  220. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
  221. data/ext/couchbase/core/operations/operation_traits.hxx +18 -0
  222. data/ext/couchbase/core/operations/query_response_parsing.cxx +211 -0
  223. data/ext/couchbase/core/operations/query_response_parsing.hxx +60 -0
  224. data/ext/couchbase/core/operations_fwd.hxx +3 -3
  225. data/ext/couchbase/core/origin.cxx +54 -26
  226. data/ext/couchbase/core/origin.hxx +12 -0
  227. data/ext/couchbase/core/orphan_reporter.cxx +2 -1
  228. data/ext/couchbase/core/platform/random.cc +7 -7
  229. data/ext/couchbase/core/protocol/client_request.cxx +2 -2
  230. data/ext/couchbase/core/protocol/client_request.hxx +38 -21
  231. data/ext/couchbase/core/protocol/client_response.cxx +11 -3
  232. data/ext/couchbase/core/protocol/client_response.hxx +27 -6
  233. data/ext/couchbase/core/protocol/cmd_append.cxx +2 -2
  234. data/ext/couchbase/core/protocol/cmd_cluster_map_change_notification.cxx +2 -2
  235. data/ext/couchbase/core/protocol/cmd_decrement.cxx +6 -6
  236. data/ext/couchbase/core/protocol/cmd_get.cxx +1 -1
  237. data/ext/couchbase/core/protocol/cmd_get_and_lock.cxx +2 -2
  238. data/ext/couchbase/core/protocol/cmd_get_and_touch.cxx +2 -2
  239. data/ext/couchbase/core/protocol/cmd_get_cluster_config.cxx +6 -4
  240. data/ext/couchbase/core/protocol/cmd_get_collection_id.cxx +2 -2
  241. data/ext/couchbase/core/protocol/cmd_get_error_map.cxx +1 -1
  242. data/ext/couchbase/core/protocol/cmd_get_meta.cxx +4 -4
  243. data/ext/couchbase/core/protocol/cmd_get_replica.cxx +1 -1
  244. data/ext/couchbase/core/protocol/cmd_hello.cxx +1 -1
  245. data/ext/couchbase/core/protocol/cmd_increment.cxx +6 -6
  246. data/ext/couchbase/core/protocol/cmd_insert.cxx +4 -4
  247. data/ext/couchbase/core/protocol/cmd_lookup_in.cxx +4 -3
  248. data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +4 -3
  249. data/ext/couchbase/core/protocol/cmd_mutate_in.cxx +10 -9
  250. data/ext/couchbase/core/protocol/cmd_mutate_in.hxx +10 -10
  251. data/ext/couchbase/core/protocol/cmd_observe_seqno.cxx +7 -7
  252. data/ext/couchbase/core/protocol/cmd_prepend.cxx +2 -2
  253. data/ext/couchbase/core/protocol/cmd_remove.cxx +2 -2
  254. data/ext/couchbase/core/protocol/cmd_replace.cxx +4 -4
  255. data/ext/couchbase/core/protocol/cmd_touch.cxx +1 -1
  256. data/ext/couchbase/core/protocol/cmd_upsert.cxx +4 -4
  257. data/ext/couchbase/core/protocol/datatype.hxx +118 -1
  258. data/ext/couchbase/core/protocol/frame_info_utils.cxx +1 -1
  259. data/ext/couchbase/core/protocol/magic.hxx +4 -0
  260. data/ext/couchbase/core/protocol/magic_fmt.hxx +3 -0
  261. data/ext/couchbase/core/protocol/server_request.hxx +3 -1
  262. data/ext/couchbase/core/protocol/status.cxx +1 -1
  263. data/ext/couchbase/core/protostellar/analytics_converter.hxx +171 -0
  264. data/ext/couchbase/core/protostellar/bucket_admin_converter.hxx +301 -0
  265. data/ext/couchbase/core/protostellar/collection_admin_converter.hxx +92 -0
  266. data/ext/couchbase/core/protostellar/component.cxx +2445 -0
  267. data/ext/couchbase/core/protostellar/component.hxx +391 -0
  268. data/ext/couchbase/core/{columnar/bootstrap_notification_subscriber.hxx → protostellar/compression_settings.hxx} +11 -10
  269. data/ext/couchbase/core/protostellar/credentials.cxx +233 -0
  270. data/ext/couchbase/core/protostellar/credentials.hxx +88 -0
  271. data/ext/couchbase/core/protostellar/dispatcher.cxx +57 -0
  272. data/ext/couchbase/core/protostellar/dispatcher.hxx +482 -0
  273. data/ext/couchbase/core/protostellar/error_utils.cxx +293 -0
  274. data/ext/couchbase/core/protostellar/error_utils.hxx +97 -0
  275. data/ext/couchbase/core/protostellar/json_payload.hxx +49 -0
  276. data/ext/couchbase/core/protostellar/kv_converter.cxx +70 -0
  277. data/ext/couchbase/core/protostellar/kv_converter.hxx +600 -0
  278. data/ext/couchbase/core/protostellar/query_converter.hxx +265 -0
  279. data/ext/couchbase/core/protostellar/query_index_admin_converter.hxx +291 -0
  280. data/ext/couchbase/core/protostellar/query_proto.hxx +73 -0
  281. data/ext/couchbase/core/protostellar/search_converter.hxx +244 -0
  282. data/ext/couchbase/core/protostellar/search_index_admin_converter.hxx +156 -0
  283. data/ext/couchbase/core/protostellar/view_converter.hxx +158 -0
  284. data/ext/couchbase/core/query_stream.cxx +447 -0
  285. data/ext/couchbase/core/query_stream.hxx +141 -0
  286. data/ext/couchbase/core/query_stream_component.cxx +243 -0
  287. data/ext/couchbase/core/query_stream_component.hxx +68 -0
  288. data/ext/couchbase/core/range_scan_load_balancer.cxx +15 -8
  289. data/ext/couchbase/core/range_scan_orchestrator.cxx +15 -3
  290. data/ext/couchbase/core/response_handler.hxx +41 -4
  291. data/ext/couchbase/core/row_streamer.cxx +332 -46
  292. data/ext/couchbase/core/row_streamer.hxx +31 -1
  293. data/ext/couchbase/core/row_streamer_options.hxx +55 -0
  294. data/ext/couchbase/core/sasl/client.h +3 -0
  295. data/ext/couchbase/core/search_scoring.hxx +66 -0
  296. data/ext/couchbase/core/stream_error_details.hxx +69 -0
  297. data/ext/couchbase/core/timeout_defaults.hxx +0 -1
  298. data/ext/couchbase/core/topology/capabilities.hxx +6 -0
  299. data/ext/couchbase/core/topology/capabilities_fmt.hxx +3 -0
  300. data/ext/couchbase/core/topology/configuration.cxx +21 -6
  301. data/ext/couchbase/core/topology/configuration.hxx +29 -8
  302. data/ext/couchbase/core/topology/configuration_json.hxx +3 -0
  303. data/ext/couchbase/core/topology/error_map_json.hxx +3 -1
  304. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +70 -4
  305. data/ext/couchbase/core/tracing/threshold_logging_tracer.hxx +10 -0
  306. data/ext/couchbase/core/transactions/active_transaction_record.cxx +0 -34
  307. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +108 -63
  308. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +19 -2
  309. data/ext/couchbase/core/transactions/error_list.hxx +2 -2
  310. data/ext/couchbase/core/transactions/get_multi_fetch.hxx +160 -0
  311. data/ext/couchbase/core/transactions/get_multi_orchestrator.cxx +326 -125
  312. data/ext/couchbase/core/transactions/get_multi_transaction_id.hxx +62 -0
  313. data/ext/couchbase/core/transactions/internal/atr_entry.hxx +22 -2
  314. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +2 -2
  315. data/ext/couchbase/core/transactions/internal/transactions_cleanup.hxx +23 -1
  316. data/ext/couchbase/core/transactions/internal/utils.hxx +50 -14
  317. data/ext/couchbase/core/transactions/staged_mutation.cxx +23 -18
  318. data/ext/couchbase/core/transactions/staged_mutation.hxx +15 -4
  319. data/ext/couchbase/core/transactions/transaction_context.cxx +55 -40
  320. data/ext/couchbase/core/transactions/transaction_get_result.hxx +16 -0
  321. data/ext/couchbase/core/transactions/transactions.cxx +3 -55
  322. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +165 -72
  323. data/ext/couchbase/core/transactions/transactions_config.cxx +0 -11
  324. data/ext/couchbase/core/transactions/utils.cxx +10 -0
  325. data/ext/couchbase/core/transactions/waitable_op_list.hxx +2 -2
  326. data/ext/couchbase/core/transactions.hxx +9 -9
  327. data/ext/couchbase/core/utils/byteswap.hxx +166 -9
  328. data/ext/couchbase/core/utils/connection_string.cxx +50 -85
  329. data/ext/couchbase/core/utils/connection_string.hxx +15 -0
  330. data/ext/couchbase/core/{columnar/backoff_calculator.hxx → utils/deadline.hxx} +13 -13
  331. data/ext/couchbase/core/utils/duration_parser.cxx +1 -1
  332. data/ext/couchbase/core/utils/json_streaming_lexer.cxx +48 -5
  333. data/ext/couchbase/core/utils/json_streaming_lexer.hxx +4 -1
  334. data/ext/couchbase/core/utils/movable_function.hxx +301 -52
  335. data/ext/couchbase/core/utils/name_codec.hxx +154 -11
  336. data/ext/couchbase/core/{columnar/retry_info.hxx → utils/process_id.hxx} +18 -13
  337. data/ext/couchbase/core/utils/url_codec.cxx +12 -51
  338. data/ext/couchbase/core/websocket_codec.cxx +13 -37
  339. data/ext/couchbase/couchbase/analytics_options.hxx +21 -10
  340. data/ext/couchbase/couchbase/analytics_row.hxx +105 -0
  341. data/ext/couchbase/couchbase/analytics_stream_result.hxx +266 -0
  342. data/ext/couchbase/couchbase/boolean_query.hxx +3 -3
  343. data/ext/couchbase/couchbase/bucket.hxx +57 -0
  344. data/ext/couchbase/couchbase/cluster.hxx +183 -5
  345. data/ext/couchbase/{core/columnar/security_options.hxx → couchbase/cluster_state.hxx} +18 -14
  346. data/ext/couchbase/couchbase/codec/lenient_json_transcoder.hxx +69 -0
  347. data/ext/couchbase/couchbase/collection.hxx +234 -14
  348. data/ext/couchbase/couchbase/common_durability_options.hxx +18 -3
  349. data/ext/couchbase/couchbase/conjunction_query.hxx +1 -1
  350. data/ext/couchbase/couchbase/create_dataset_analytics_options.hxx +6 -1
  351. data/ext/couchbase/couchbase/date_range_query.hxx +2 -2
  352. data/ext/couchbase/couchbase/decrement_options.hxx +1 -1
  353. data/ext/couchbase/couchbase/disjunction_query.hxx +1 -1
  354. data/ext/couchbase/couchbase/error.hxx +32 -0
  355. data/ext/couchbase/couchbase/error_codes.hxx +33 -1
  356. data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +1 -1
  357. data/ext/couchbase/couchbase/geo_distance_query.hxx +1 -1
  358. data/ext/couchbase/couchbase/geo_polygon_query.hxx +1 -1
  359. data/ext/couchbase/couchbase/get_replica_options.hxx +68 -0
  360. data/ext/couchbase/couchbase/get_replica_result.hxx +5 -3
  361. data/ext/couchbase/couchbase/get_replica_strategy.hxx +161 -0
  362. data/ext/couchbase/couchbase/get_result.hxx +1 -0
  363. data/ext/couchbase/couchbase/increment_options.hxx +1 -1
  364. data/ext/couchbase/couchbase/insert_options.hxx +1 -1
  365. data/ext/couchbase/couchbase/match_phrase_query.hxx +1 -1
  366. data/ext/couchbase/couchbase/match_query.hxx +1 -1
  367. data/ext/couchbase/couchbase/mutate_in_options.hxx +3 -3
  368. data/ext/couchbase/couchbase/network_options.hxx +1 -1
  369. data/ext/couchbase/couchbase/node_id.hxx +42 -14
  370. data/ext/couchbase/couchbase/node_id_for_options.hxx +7 -1
  371. data/ext/couchbase/couchbase/node_ids_options.hxx +8 -2
  372. data/ext/couchbase/couchbase/numeric_range_query.hxx +1 -1
  373. data/ext/couchbase/couchbase/phrase_query.hxx +1 -1
  374. data/ext/couchbase/couchbase/prefix_query.hxx +1 -1
  375. data/ext/couchbase/couchbase/query_options.hxx +23 -12
  376. data/ext/couchbase/couchbase/query_row.hxx +111 -0
  377. data/ext/couchbase/couchbase/query_stream_result.hxx +302 -0
  378. data/ext/couchbase/couchbase/query_string_query.hxx +3 -3
  379. data/ext/couchbase/couchbase/regexp_query.hxx +1 -1
  380. data/ext/couchbase/couchbase/replace_options.hxx +3 -3
  381. data/ext/couchbase/couchbase/result.hxx +14 -3
  382. data/ext/couchbase/couchbase/scan_result_item.hxx +1 -0
  383. data/ext/couchbase/couchbase/scope.hxx +85 -2
  384. data/ext/couchbase/couchbase/search_options.hxx +58 -8
  385. data/ext/couchbase/couchbase/search_scoring.hxx +94 -0
  386. data/ext/couchbase/couchbase/search_scoring_none.hxx +51 -0
  387. data/ext/couchbase/couchbase/search_scoring_reciprocal_rank_fusion.hxx +88 -0
  388. data/ext/couchbase/couchbase/search_scoring_relative_score_fusion.hxx +70 -0
  389. data/ext/couchbase/couchbase/term_range_query.hxx +1 -1
  390. data/ext/couchbase/couchbase/tracing/request_span.hxx +46 -0
  391. data/ext/couchbase/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +23 -21
  392. data/ext/couchbase/couchbase/transactions/transaction_get_multi_result.hxx +24 -19
  393. data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +17 -3
  394. data/ext/couchbase/couchbase/transactions/transactions_config.hxx +4 -2
  395. data/ext/couchbase/couchbase/transactions.hxx +27 -18
  396. data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
  397. data/ext/couchbase/couchbase/vector_query.hxx +1 -1
  398. data/ext/couchbase/couchbase/wait_until_ready_options.hxx +111 -0
  399. data/ext/couchbase/couchbase/wildcard_query.hxx +1 -1
  400. data/ext/extconf.rb +15 -10
  401. data/ext/rcb_analytics.cxx +82 -102
  402. data/ext/rcb_backend.cxx +42 -36
  403. data/ext/rcb_backend.hxx +2 -0
  404. data/ext/rcb_buckets.cxx +47 -59
  405. data/ext/rcb_collections.cxx +42 -52
  406. data/ext/rcb_crud.cxx +345 -224
  407. data/ext/rcb_diagnostics.cxx +117 -27
  408. data/ext/rcb_exceptions.cxx +152 -99
  409. data/ext/rcb_exceptions.hxx +25 -0
  410. data/ext/rcb_extras.cxx +18 -19
  411. data/ext/rcb_hdr_histogram.cxx +19 -4
  412. data/ext/rcb_logger.cxx +202 -27
  413. data/ext/rcb_logger.hxx +12 -0
  414. data/ext/rcb_multi.cxx +40 -40
  415. data/ext/rcb_observability.cxx +7 -5
  416. data/ext/rcb_query.cxx +99 -142
  417. data/ext/rcb_range_scan.cxx +41 -35
  418. data/ext/rcb_search.cxx +98 -99
  419. data/ext/rcb_users.cxx +36 -56
  420. data/ext/rcb_utils.cxx +100 -37
  421. data/ext/rcb_utils.hxx +287 -33
  422. data/ext/rcb_version.cxx +1 -1
  423. data/ext/rcb_views.cxx +55 -51
  424. data/lib/active_support/cache/couchbase_store.rb +77 -12
  425. data/lib/couchbase/bucket.rb +20 -0
  426. data/lib/couchbase/cluster.rb +17 -0
  427. data/lib/couchbase/collection.rb +36 -1
  428. data/lib/couchbase/errors.rb +18 -0
  429. data/lib/couchbase/fork_hooks.rb +16 -7
  430. data/lib/couchbase/get_replica_strategy.rb +89 -0
  431. data/lib/couchbase/logger.rb +1 -1
  432. data/lib/couchbase/management/analytics_index_manager.rb +15 -15
  433. data/lib/couchbase/management/bucket_manager.rb +6 -6
  434. data/lib/couchbase/management/collection_manager.rb +6 -6
  435. data/lib/couchbase/management/query_index_manager.rb +7 -7
  436. data/lib/couchbase/management/search_index_manager.rb +13 -13
  437. data/lib/couchbase/management/user_manager.rb +10 -10
  438. data/lib/couchbase/management/view_index_manager.rb +5 -5
  439. data/lib/couchbase/options.rb +174 -42
  440. data/lib/couchbase/protostellar/bucket.rb +4 -0
  441. data/lib/couchbase/protostellar/cluster.rb +4 -0
  442. data/lib/couchbase/protostellar/collection.rb +4 -0
  443. data/lib/couchbase/protostellar/error_handling.rb +2 -1
  444. data/lib/couchbase/protostellar/request.rb +1 -0
  445. data/lib/couchbase/protostellar/request_generator/kv.rb +16 -2
  446. data/lib/couchbase/protostellar/request_generator/search.rb +17 -1
  447. data/lib/couchbase/protostellar/retry/orchestrator.rb +3 -2
  448. data/lib/couchbase/protostellar/retry/strategies/fail_fast.rb +33 -0
  449. data/lib/couchbase/protostellar/retry/strategies.rb +1 -0
  450. data/lib/couchbase/search_options.rb +95 -6
  451. data/lib/couchbase/version.rb +1 -1
  452. metadata +91 -33
  453. data/ext/0001-fix-build-for-mingw-w64-ucrt-x86_64-toolchain.patch +0 -40
  454. data/ext/couchbase/core/columnar/agent.hxx +0 -71
  455. data/ext/couchbase/core/columnar/agent_config.hxx +0 -59
  456. data/ext/couchbase/core/columnar/background_bootstrap_listener.hxx +0 -42
  457. data/ext/couchbase/core/columnar/backoff_calculator.cxx +0 -62
  458. data/ext/couchbase/core/columnar/columnar_agent.cxx +0 -147
  459. data/ext/couchbase/core/columnar/columnar_agent_config.cxx +0 -48
  460. data/ext/couchbase/core/columnar/columnar_error.cxx +0 -51
  461. data/ext/couchbase/core/columnar/database_management_options.hxx +0 -56
  462. data/ext/couchbase/core/columnar/error.hxx +0 -51
  463. data/ext/couchbase/core/columnar/error_codes.cxx +0 -107
  464. data/ext/couchbase/core/columnar/error_codes.hxx +0 -75
  465. data/ext/couchbase/core/columnar/management_component.cxx +0 -300
  466. data/ext/couchbase/core/columnar/management_component.hxx +0 -56
  467. data/ext/couchbase/core/columnar/query_component.cxx +0 -523
  468. data/ext/couchbase/core/columnar/query_component.hxx +0 -57
  469. data/ext/couchbase/core/columnar/query_options.hxx +0 -59
  470. data/ext/couchbase/core/columnar/query_result.cxx +0 -130
  471. data/ext/couchbase/core/columnar/query_result.hxx +0 -78
  472. data/ext/couchbase/core/io/config_tracker.cxx +0 -687
  473. data/ext/couchbase/core/io/config_tracker.hxx +0 -123
@@ -73,7 +73,7 @@ is_already_escape(T first, T last) -> bool
73
73
  ++first; // ignore '%'
74
74
  std::size_t jj = 0;
75
75
  for (; first != last && jj < 2; ++jj, ++first) {
76
- if (!isxdigit(*first)) {
76
+ if (isxdigit(static_cast<unsigned char>(*first)) == 0) {
77
77
  return false;
78
78
  }
79
79
  }
@@ -81,57 +81,22 @@ is_already_escape(T first, T last) -> bool
81
81
  }
82
82
  } // namespace priv
83
83
 
84
+ // Each byte is decided on its own: with check_encoded, an existing %XX escape is copied as is, a
85
+ // legal URI character is copied, and every other byte is written as %XX.
84
86
  template<typename Ti, typename To>
85
- auto
86
- url_encode(Ti first, Ti last, To& o, bool check_encoded = true) -> bool
87
+ void
88
+ url_encode(Ti first, Ti last, To& o, bool check_encoded = true)
87
89
  {
88
- // If re-encoding detection is enabled, this flag indicates not to
89
- // re-encode
90
- bool skip_encoding = false;
91
-
92
90
  for (; first != last; ++first) {
93
- if (!skip_encoding && check_encoded) {
94
- if (*first == '%') {
95
- skip_encoding = priv::is_already_escape(first, last);
96
- } else if (*first == '+') {
97
- skip_encoding = true;
98
- }
99
- }
100
- if (skip_encoding || priv::is_legal_uri_char(*first)) {
101
- if (skip_encoding && *first != '%' && !priv::is_legal_uri_char(*first)) {
102
- return false;
103
- }
104
-
91
+ if (check_encoded && *first == '%' && priv::is_already_escape(first, last)) {
92
+ o.insert(o.end(), first, first + 3);
93
+ first += 2;
94
+ } else if (priv::is_legal_uri_char(*first)) {
105
95
  o.insert(o.end(), first, first + 1);
106
96
  } else {
107
- const unsigned int c = static_cast<unsigned char>(*first);
108
- std::size_t numbytes = 0;
109
-
110
- if ((c & 0x80) == 0) { /* ASCII character */
111
- numbytes = 1;
112
- } else if ((c & 0xE0) == 0xC0) { /* 110x xxxx */
113
- numbytes = 2;
114
- } else if ((c & 0xF0) == 0xE0) { /* 1110 xxxx */
115
- numbytes = 3;
116
- } else if ((c & 0xF8) == 0xF0) { /* 1111 0xxx */
117
- numbytes = 4;
118
- } else {
119
- return false;
120
- }
121
-
122
- do {
123
- o.append(fmt::format("%{:x}", static_cast<std::uint8_t>(*first)));
124
- } while (--numbytes && ++first != last);
97
+ o.append(fmt::format("%{:02x}", static_cast<std::uint8_t>(*first)));
125
98
  }
126
99
  }
127
- return true;
128
- }
129
-
130
- template<typename Tin, typename Tout>
131
- auto
132
- url_encode(const Tin& in, Tout& out) -> bool
133
- {
134
- return url_encode(in.begin(), in.end(), out);
135
100
  }
136
101
 
137
102
  auto
@@ -212,18 +177,14 @@ form_encode(Ti first, Ti last, To& out)
212
177
  {
213
178
  for (; first != last; ++first) {
214
179
  auto c = static_cast<unsigned char>(*first);
215
- if (isalnum(c)) {
216
- out.insert(out.end(), first, first + 1);
217
- continue;
218
- }
219
180
  if (c == ' ') {
220
181
  char tmp = '+';
221
182
  out.insert(out.end(), &tmp, &tmp + 1);
222
183
  } else if ((c == 0x2A || c == 0x2D || c == 0x2E) || (c >= 0x30 && c <= 0x39) ||
223
- (c >= 0x41 && c <= 0x5A) || (c == 0x5F) || (c >= 0x60 && c <= 0x7A)) {
184
+ (c >= 0x41 && c <= 0x5A) || (c == 0x5F) || (c >= 0x61 && c <= 0x7A)) {
224
185
  out.insert(out.end(), static_cast<char>(c));
225
186
  } else {
226
- out.append(fmt::format("%{:x}", static_cast<std::uint8_t>(*first)));
187
+ out.append(fmt::format("%{:02x}", static_cast<std::uint8_t>(*first)));
227
188
  }
228
189
  }
229
190
  }
@@ -16,6 +16,7 @@
16
16
  #include "websocket_codec.hxx"
17
17
 
18
18
  #include "core/crypto/cbcrypto.h"
19
+ #include "core/mcbp/big_endian.hxx"
19
20
  #include "core/platform/base64.h"
20
21
  #include "core/platform/random.h"
21
22
 
@@ -25,7 +26,6 @@
25
26
  #include <algorithm>
26
27
  #include <array>
27
28
  #include <cstdint>
28
- #include <cstring>
29
29
  #include <map>
30
30
  #include <optional>
31
31
  #include <random>
@@ -443,45 +443,21 @@ encode_payload_length(std::size_t length) -> std::vector<std::byte>
443
443
  }
444
444
  // 7 + 64
445
445
  constexpr std::uint8_t field_7_bit = 127 | flag_mask;
446
+ // std::size_t is 32 bits on 32-bit targets, where shifting it by 32 or more is undefined.
447
+ const std::uint64_t wide_length = length;
446
448
  return {
447
449
  std::byte{ field_7_bit },
448
- static_cast<std::byte>((length >> 56) & 0xff),
449
- static_cast<std::byte>((length >> 48) & 0xff),
450
- static_cast<std::byte>((length >> 40) & 0xff),
451
- static_cast<std::byte>((length >> 32) & 0xff),
452
- static_cast<std::byte>((length >> 24) & 0xff),
453
- static_cast<std::byte>((length >> 16) & 0xff),
454
- static_cast<std::byte>((length >> 8) & 0xff),
455
- static_cast<std::byte>(length & 0xff),
450
+ static_cast<std::byte>((wide_length >> 56) & 0xff),
451
+ static_cast<std::byte>((wide_length >> 48) & 0xff),
452
+ static_cast<std::byte>((wide_length >> 40) & 0xff),
453
+ static_cast<std::byte>((wide_length >> 32) & 0xff),
454
+ static_cast<std::byte>((wide_length >> 24) & 0xff),
455
+ static_cast<std::byte>((wide_length >> 16) & 0xff),
456
+ static_cast<std::byte>((wide_length >> 8) & 0xff),
457
+ static_cast<std::byte>(wide_length & 0xff),
456
458
  };
457
459
  }
458
460
 
459
- auto
460
- decode_uint64(gsl::span<std::byte> data) -> std::uint64_t
461
- {
462
- std::uint64_t result{};
463
- std::memcpy(&result, data.data(), sizeof(result));
464
-
465
- return //
466
- (result & 0x00000000000000FF) << 56 | //
467
- (result & 0x000000000000FF00) << 40 | //
468
- (result & 0x0000000000FF0000) << 24 | //
469
- (result & 0x00000000FF000000) << 8 | //
470
- (result & 0x000000FF00000000) >> 8 | //
471
- (result & 0x0000FF0000000000) >> 24 | //
472
- (result & 0x00FF000000000000) >> 40 | //
473
- (result & 0xFF00000000000000) >> 56;
474
- }
475
-
476
- auto
477
- decode_uint16(gsl::span<std::byte> data) -> std::uint16_t
478
- {
479
- std::uint16_t result{};
480
- std::memcpy(&result, data.data(), sizeof(result));
481
-
482
- return static_cast<std::uint16_t>(result << 8 | result >> 8);
483
- }
484
-
485
461
  auto
486
462
  decode_frame(gsl::span<std::byte> data, bool expected_continuation) -> decode_status
487
463
  {
@@ -519,7 +495,7 @@ decode_frame(gsl::span<std::byte> data, bool expected_continuation) -> decode_st
519
495
  return need_more_data{};
520
496
  }
521
497
  header_length = 10;
522
- payload_length = decode_uint64(data.subspan(2, sizeof(std::uint64_t)));
498
+ payload_length = mcbp::big_endian::read_uint64(data, 2);
523
499
  break;
524
500
 
525
501
  case 126:
@@ -527,7 +503,7 @@ decode_frame(gsl::span<std::byte> data, bool expected_continuation) -> decode_st
527
503
  return need_more_data{};
528
504
  }
529
505
  header_length = 4;
530
- payload_length = decode_uint16(data.subspan(2, sizeof(std::uint16_t)));
506
+ payload_length = mcbp::big_endian::read_uint16(data, 2);
531
507
  break;
532
508
 
533
509
  default:
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include <couchbase/analytics_result.hxx>
21
21
  #include <couchbase/analytics_scan_consistency.hxx>
22
+ #include <couchbase/analytics_stream_result.hxx>
22
23
  #include <couchbase/common_options.hxx>
23
24
  #include <couchbase/error.hxx>
24
25
  #include <couchbase/mutation_state.hxx>
@@ -181,10 +182,11 @@ struct analytics_options : public common_options<analytics_options> {
181
182
  * mutations. If you want to include all the mutations up to the point of the query, use {@link
182
183
  * analytics_scan_consistency::request_plus}.
183
184
  *
184
- * Note that you cannot use this method and {@link #consistent_with(const mutation_state&)} at the
185
- * same time, since they are mutually exclusive. As a rule of thumb, if you only care to be
186
- * consistent with the mutation you just wrote on the same thread/app, use
187
- * {@link #consistent_with(const mutation_state&)}. If you need "global" scan consistency, use
185
+ * Note that you cannot use this method and {@link #consistent_with consistent_with(const
186
+ * mutation_state&)} at the same time, since they are mutually exclusive. As a rule of thumb, if
187
+ * you only care to be consistent with the mutation you just wrote on the same thread/app, use
188
+ * {@link #consistent_with consistent_with(const mutation_state&)}. If you need "global" scan
189
+ * consistency, use
188
190
  * {@link analytics_scan_consistency::request_plus} on this method.
189
191
  *
190
192
  * @param scan_consistency the index scan consistency to be used for this query
@@ -207,12 +209,12 @@ struct analytics_options : public common_options<analytics_options> {
207
209
  * and if you want your N1QL query to include those you need to pass the mutation tokens into a
208
210
  * {@link mutation_state}.
209
211
  *
210
- * Note that you cannot use this method and {@link #scan_consistency(analytics_scan_consistency)}
211
- * at the same time, since they are mutually exclusive. As a rule of thumb, if you only care to be
212
- * consistent with the mutation you just wrote on the same thread/app, use this method. If you
213
- * need "global" scan consistency, use
214
- * {@link analytics_scan_consistency#request_plus} on {@link
215
- * #scan_consistency(analytics_scan_consistency)}.
212
+ * Note that you cannot use this method and {@link #scan_consistency
213
+ * scan_consistency(analytics_scan_consistency)} at the same time, since they are mutually
214
+ * exclusive. As a rule of thumb, if you only care to be consistent with the mutation you just
215
+ * wrote on the same thread/app, use this method. If you need "global" scan consistency, use
216
+ * {@link analytics_scan_consistency#request_plus} on {@link #scan_consistency
217
+ * scan_consistency(analytics_scan_consistency)}.
216
218
  *
217
219
  * @param state the mutation state containing the mutation tokens.
218
220
  * @return this options builder for chaining purposes.
@@ -463,4 +465,13 @@ private:
463
465
  * @uncommitted
464
466
  */
465
467
  using analytics_handler = std::function<void(error, analytics_result)>;
468
+
469
+ /**
470
+ * The signature for the handler of the @ref cluster#analytics_query_stream() and @ref
471
+ * scope#analytics_query_stream() operations
472
+ *
473
+ * @since 1.4.0
474
+ * @volatile
475
+ */
476
+ using analytics_stream_handler = std::function<void(error, analytics_stream_result)>;
466
477
  } // namespace couchbase
@@ -0,0 +1,105 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-Present 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 <couchbase/codec/encoded_value.hxx>
21
+ #include <couchbase/codec/serializer_traits.hxx>
22
+ #include <utility>
23
+
24
+ namespace couchbase
25
+ {
26
+
27
+ namespace codec
28
+ {
29
+ class tao_json_serializer;
30
+ } // namespace codec
31
+
32
+ /**
33
+ * Represents a single row of a streaming analytics result.
34
+ *
35
+ * The raw JSON bytes can be decoded via @ref content_as().
36
+ *
37
+ * @since 1.4.0
38
+ * @volatile
39
+ */
40
+ class analytics_row
41
+ {
42
+ public:
43
+ /**
44
+ * @since 1.4.0
45
+ * @volatile
46
+ */
47
+ analytics_row() = default;
48
+
49
+ /**
50
+ * Constructs a row from raw JSON bytes.
51
+ *
52
+ * @param content raw JSON bytes for this row
53
+ *
54
+ * @since 1.4.0
55
+ * @volatile
56
+ */
57
+ explicit analytics_row(codec::binary content)
58
+ : content_{ std::move(content) }
59
+ {
60
+ }
61
+
62
+ /**
63
+ * Decodes the row content into the requested document type using the given serializer.
64
+ *
65
+ * Only call this on a row obtained from a successful @ref analytics_stream_result#next() (falsy
66
+ * error, engaged optional). The end-of-stream and error sentinels carry an empty @ref
67
+ * analytics_row, and decoding empty/malformed content throws the serializer's parse exception —
68
+ * gate on the three-state next() contract (check the error, then the optional) before decoding.
69
+ *
70
+ * @snippet{trimleft} test_integration_examples_streaming.cxx example-analytics-stream
71
+ *
72
+ * @tparam Serializer the serializer to use (defaults to @ref codec::tao_json_serializer)
73
+ * @tparam Document the document type to decode into (defaults to the serializer's document_type)
74
+ * @return the decoded document
75
+ * @throws the serializer's deserialization exception if the content is empty or not valid JSON
76
+ *
77
+ * @since 1.4.0
78
+ * @volatile
79
+ */
80
+ template<typename Serializer = codec::tao_json_serializer,
81
+ typename Document = typename Serializer::document_type,
82
+ std::enable_if_t<codec::is_serializer_v<Serializer>, bool> = true>
83
+ [[nodiscard]] auto content_as() const -> Document
84
+ {
85
+ return Serializer::template deserialize<Document>(content_);
86
+ }
87
+
88
+ /**
89
+ * Returns the raw binary content of this row.
90
+ *
91
+ * @return raw JSON bytes
92
+ *
93
+ * @since 1.4.0
94
+ * @volatile
95
+ */
96
+ [[nodiscard]] auto content_as_binary() const -> const codec::binary&
97
+ {
98
+ return content_;
99
+ }
100
+
101
+ private:
102
+ codec::binary content_{};
103
+ };
104
+
105
+ } // namespace couchbase
@@ -0,0 +1,266 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2026. 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 <couchbase/analytics_meta_data.hxx>
21
+ #include <couchbase/analytics_row.hxx>
22
+ #include <couchbase/codec/encoded_value.hxx>
23
+ #include <couchbase/error.hxx>
24
+
25
+ #include <functional>
26
+ #include <future>
27
+ #include <memory>
28
+ #include <optional>
29
+ #include <utility>
30
+
31
+ namespace couchbase
32
+ {
33
+ #ifndef COUCHBASE_CXX_CLIENT_DOXYGEN
34
+ class internal_analytics_stream_result;
35
+ #endif
36
+
37
+ /**
38
+ * The signature for the handler of the @ref analytics_stream_result#next() operation.
39
+ *
40
+ * @since 1.4.0
41
+ * @volatile
42
+ */
43
+ using analytics_row_handler = std::function<void(error, std::optional<analytics_row>)>;
44
+
45
+ /**
46
+ * A streaming result handle for analytics queries.
47
+ *
48
+ * Rows are fetched one at a time via @ref next(). The stream must be fully drained
49
+ * (or @ref cancel() called) before @ref meta_data() resolves. Only a single @ref next()
50
+ * call may be outstanding at a time.
51
+ *
52
+ * @snippet{trimleft} test_integration_examples_streaming.cxx example-analytics-stream
53
+ *
54
+ * @note The future-returning overloads (`next()`, `meta_data()`) and the eager @ref iterator
55
+ * block the calling thread until the result is ready. They must not be called from within an SDK
56
+ * completion handler (i.e. the library's I/O thread) — doing so blocks that thread against itself
57
+ * and the stream can never advance. From a completion handler, use the callback @ref next()
58
+ * overload instead.
59
+ *
60
+ * @note Copies of a result handle share one underlying stream: they alias the same rows, the same
61
+ * single-outstanding-next() budget, and the same @ref cancel(). Copying does not fork the stream;
62
+ * a @ref next() on any copy consumes the next row for all of them. Use a single handle per stream.
63
+ *
64
+ * @since 1.4.0
65
+ * @volatile
66
+ */
67
+ class analytics_stream_result
68
+ {
69
+ public:
70
+ /**
71
+ * Constructs an empty (no-op) result handle.
72
+ *
73
+ * @since 1.4.0
74
+ * @internal
75
+ */
76
+ analytics_stream_result() = default;
77
+
78
+ /**
79
+ * Constructs an analytics stream result from an internal result.
80
+ *
81
+ * @param internal the internal result handle
82
+ *
83
+ * @since 1.4.0
84
+ * @internal
85
+ */
86
+ explicit analytics_stream_result(std::shared_ptr<internal_analytics_stream_result> internal);
87
+
88
+ /**
89
+ * Fetches the next row asynchronously, invoking the handler when ready.
90
+ *
91
+ * The handler receives ({}, row) for a real row, ({}, {}) at clean end-of-stream,
92
+ * or (error, {}) if the stream ended with an error.
93
+ *
94
+ * Only one outstanding call is allowed at a time.
95
+ *
96
+ * @param handler callable that implements @ref analytics_row_handler
97
+ *
98
+ * @since 1.4.0
99
+ * @volatile
100
+ */
101
+ void next(analytics_row_handler&& handler) const;
102
+
103
+ /**
104
+ * Fetches the next row, returning a future.
105
+ *
106
+ * Only one outstanding call is allowed at a time.
107
+ *
108
+ * @return future object that carries the result of the operation
109
+ *
110
+ * @since 1.4.0
111
+ * @volatile
112
+ */
113
+ [[nodiscard]] auto next() const -> std::future<std::pair<error, std::optional<analytics_row>>>;
114
+
115
+ /**
116
+ * Returns the analytics signature captured from the response metadata, if present.
117
+ *
118
+ * The signature is part of the response preamble, so — unlike @ref meta_data() — it is available
119
+ * as soon as the stream has started, without draining it first:
120
+ *
121
+ * @snippet{trimleft} test_integration_examples_streaming.cxx example-analytics-stream
122
+ *
123
+ * @return optional binary JSON signature
124
+ *
125
+ * @since 1.4.0
126
+ * @volatile
127
+ */
128
+ [[nodiscard]] auto signature() const -> std::optional<codec::binary>;
129
+
130
+ /**
131
+ * Returns the analytics metadata.
132
+ *
133
+ * The returned future resolves only after the stream has been fully drained
134
+ * (all rows consumed or the stream cancelled). May be called more than once;
135
+ * each call returns its own future and all of them resolve together once the
136
+ * metadata becomes available.
137
+ *
138
+ * @return future carrying (error, analytics_meta_data)
139
+ *
140
+ * @since 1.4.0
141
+ * @volatile
142
+ */
143
+ [[nodiscard]] auto meta_data() const -> std::future<std::pair<error, analytics_meta_data>>;
144
+
145
+ /**
146
+ * Cancels the stream and closes the underlying HTTP connection.
147
+ *
148
+ * Simply dropping the last handle before the stream is fully drained also tears the stream down,
149
+ * but if a pull is in flight the underlying connection is not released until that pull settles
150
+ * (up to the inter-read idle timeout). Call cancel() explicitly for prompt, deterministic
151
+ * teardown of the connection and its timers.
152
+ *
153
+ * @since 1.4.0
154
+ * @volatile
155
+ */
156
+ void cancel() const;
157
+
158
+ /**
159
+ * Sentinel returned by @ref end(). An @ref iterator compares equal to it once the stream has been
160
+ * fully drained (after any terminal error element). Using a distinct end type means iterators are
161
+ * only ever compared against the end sentinel, never against one another.
162
+ *
163
+ * @since 1.4.0
164
+ * @volatile
165
+ */
166
+ struct end_sentinel {
167
+ };
168
+
169
+ /**
170
+ * A single-pass input iterator that synchronously fetches rows one at a time.
171
+ *
172
+ * Dereferencing yields `std::pair<error, analytics_row>`: for a data row the error is falsy; if
173
+ * the stream ends with an error, the iterator visits exactly one final element whose error is
174
+ * truthy (and whose row is empty) before comparing equal to @ref end(). A clean end-of-stream
175
+ * yields no such element. This guarantees a `for (auto [err, row] : result)` loop can observe a
176
+ * terminal error rather than silently stopping.
177
+ *
178
+ * This is a minimal single-pass iterator intended for range-based for and manual
179
+ * `while (it != result.end())` loops. It compares only against @ref end() (never against another
180
+ * iterator), and provides neither `operator->` nor post-increment, so it is deliberately not a
181
+ * `LegacyInputIterator` and does not work with `<algorithm>` or `std::distance`. @ref begin()
182
+ * must be called once.
183
+ *
184
+ * @since 1.4.0
185
+ * @volatile
186
+ */
187
+ class iterator
188
+ {
189
+ public:
190
+ auto operator*() const -> std::pair<error, analytics_row>;
191
+ auto operator++() -> iterator&;
192
+
193
+ /**
194
+ * Constructs an iterator over an internal result; prefer @ref begin().
195
+ *
196
+ * @since 1.4.0
197
+ * @internal
198
+ */
199
+ explicit iterator(std::shared_ptr<internal_analytics_stream_result> internal);
200
+
201
+ /**
202
+ * Compares an iterator against the end sentinel. Provided in both argument orders (and as
203
+ * both @c == and @c !=) so the range-for idiom, `while (it != result.end())` loops, and wrapper
204
+ * code all work regardless of which operand is written first. Iterators are intentionally never
205
+ * comparable to one another: a single-pass stream has one position, so iterator-to-iterator
206
+ * equality would be meaningless — the type only ever compares against @ref end().
207
+ */
208
+ friend auto operator==(const iterator& it, end_sentinel /* end */) -> bool
209
+ {
210
+ return it.terminal_;
211
+ }
212
+ friend auto operator==(end_sentinel end, const iterator& it) -> bool
213
+ {
214
+ return it == end;
215
+ }
216
+ friend auto operator!=(const iterator& it, end_sentinel end) -> bool
217
+ {
218
+ return !(it == end);
219
+ }
220
+ friend auto operator!=(end_sentinel end, const iterator& it) -> bool
221
+ {
222
+ return !(it == end);
223
+ }
224
+
225
+ // Intentionally no std::iterator_traits typedefs (notably no iterator_category). This is a
226
+ // deliberately minimal single-pass iterator for range-based for and `while (it !=
227
+ // result.end())` loops only (see the class doc); it omits post-increment and operator->.
228
+ // Declaring an input_iterator_tag while omitting those would falsely advertise
229
+ // LegacyInputIterator / std::input_iterator conformance and could break generic code that
230
+ // trusts iterator_traits. Range-based for needs none of these typedefs.
231
+
232
+ private:
233
+ void fetch_item();
234
+
235
+ std::shared_ptr<internal_analytics_stream_result> internal_{};
236
+ std::pair<error, analytics_row> item_{};
237
+ bool terminal_{ false };
238
+ // Set when fetch_item() lands on a terminal error: the error element is delivered once (the
239
+ // iterator is not yet equal to end()), and the next increment advances to true end.
240
+ bool error_pending_{ false };
241
+ };
242
+
243
+ /**
244
+ * Returns an iterator to the beginning.
245
+ *
246
+ * @return iterator to the first row
247
+ *
248
+ * @since 1.4.0
249
+ * @volatile
250
+ */
251
+ [[nodiscard]] auto begin() const -> iterator;
252
+
253
+ /**
254
+ * Returns the end sentinel.
255
+ *
256
+ * @return sentinel that an @ref iterator compares equal to once the stream is drained
257
+ *
258
+ * @since 1.4.0
259
+ * @volatile
260
+ */
261
+ [[nodiscard]] auto end() const -> end_sentinel;
262
+
263
+ private:
264
+ std::shared_ptr<internal_analytics_stream_result> internal_{};
265
+ };
266
+ } // namespace couchbase
@@ -47,11 +47,11 @@ namespace couchbase
47
47
  * In the example below the following rules enforced by the boolean query:
48
48
  * * retrieved documents MUST match `"hostel room"` in their `reviews.content` field AND have `true`
49
49
  * in `free_breakfast` field.
50
- * * also the documents SHOULD have EITHER `reviews.ratings.Overall > 4` OR `reviews.ratings.Service
51
- * > 5`.
50
+ * * also the documents SHOULD have EITHER `reviews.ratings.Overall > 4` OR
51
+ * `reviews.ratings.Service > 5`.
52
52
  * * and finally, exclude documents with `city` `"Padfield"` or `"Gilingham"`.
53
53
  *
54
- * @snippet{trimleft} test_unit_search.cxx search-boolean
54
+ * @snippet{trimleft} unit/management/search.cxx search-boolean
55
55
  *
56
56
  * @see https://docs.couchbase.com/server/current/fts/fts-supported-queries-boolean-field-query.html
57
57
  * server documentation