couchbase 3.0.0.alpha.3 → 3.0.0.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-6.0.3.yml +4 -1
  3. data/.github/workflows/tests-dev-preview.yml +4 -1
  4. data/.github/workflows/tests.yml +4 -1
  5. data/README.md +1 -1
  6. data/bin/check-cluster +31 -0
  7. data/bin/init-cluster +16 -4
  8. data/examples/analytics.rb +221 -0
  9. data/examples/managing_analytics_indexes.rb +72 -0
  10. data/examples/managing_view_indexes.rb +54 -0
  11. data/examples/search_with_consistency.rb +84 -0
  12. data/examples/view.rb +50 -0
  13. data/ext/.clang-tidy +1 -0
  14. data/ext/build_version.hxx.in +1 -1
  15. data/ext/couchbase/bucket.hxx +0 -1
  16. data/ext/couchbase/couchbase.cxx +1421 -55
  17. data/ext/couchbase/io/dns_client.hxx +215 -0
  18. data/ext/couchbase/io/dns_codec.hxx +207 -0
  19. data/ext/couchbase/io/dns_config.hxx +116 -0
  20. data/ext/couchbase/io/dns_message.hxx +558 -0
  21. data/ext/couchbase/io/http_session.hxx +16 -4
  22. data/ext/couchbase/io/mcbp_session.hxx +2 -1
  23. data/ext/couchbase/mutation_token.hxx +1 -1
  24. data/ext/couchbase/operations.hxx +19 -0
  25. data/ext/couchbase/operations/analytics_dataset_create.hxx +117 -0
  26. data/ext/couchbase/operations/analytics_dataset_drop.hxx +103 -0
  27. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +107 -0
  28. data/ext/couchbase/operations/analytics_dataverse_create.hxx +104 -0
  29. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +104 -0
  30. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +91 -0
  31. data/ext/couchbase/operations/analytics_index_create.hxx +128 -0
  32. data/ext/couchbase/operations/analytics_index_drop.hxx +110 -0
  33. data/ext/couchbase/operations/analytics_index_get_all.hxx +106 -0
  34. data/ext/couchbase/operations/analytics_link_connect.hxx +102 -0
  35. data/ext/couchbase/operations/analytics_link_disconnect.hxx +101 -0
  36. data/ext/couchbase/operations/design_document.hxx +59 -0
  37. data/ext/couchbase/operations/document_analytics.hxx +293 -0
  38. data/ext/couchbase/operations/document_query.hxx +2 -2
  39. data/ext/couchbase/operations/document_search.hxx +19 -1
  40. data/ext/couchbase/operations/document_view.hxx +227 -0
  41. data/ext/couchbase/operations/search_index.hxx +17 -0
  42. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -1
  43. data/ext/couchbase/operations/view_index_drop.hxx +67 -0
  44. data/ext/couchbase/operations/view_index_get.hxx +90 -0
  45. data/ext/couchbase/operations/view_index_get_all.hxx +125 -0
  46. data/ext/couchbase/operations/view_index_upsert.hxx +87 -0
  47. data/ext/couchbase/service_type.hxx +38 -1
  48. data/ext/couchbase/timeout_defaults.hxx +3 -1
  49. data/ext/couchbase/utils/connection_string.hxx +231 -0
  50. data/ext/couchbase/version.hxx +1 -1
  51. data/ext/test/main.cxx +3 -12
  52. data/lib/couchbase/analytics_options.rb +165 -0
  53. data/lib/couchbase/bucket.rb +49 -0
  54. data/lib/couchbase/cluster.rb +46 -207
  55. data/lib/couchbase/management/analytics_index_manager.rb +138 -24
  56. data/lib/couchbase/management/view_index_manager.rb +63 -10
  57. data/lib/couchbase/query_options.rb +219 -0
  58. data/lib/couchbase/search_options.rb +6 -6
  59. data/lib/couchbase/version.rb +1 -1
  60. data/lib/couchbase/view_options.rb +155 -0
  61. metadata +34 -2
@@ -222,7 +222,11 @@ class http_session : public std::enable_shared_from_this
222
222
  return;
223
223
  }
224
224
  if (ec && ec != asio::error::operation_aborted) {
225
- spdlog::error("IO error while reading from the socket: {}", ec.message());
225
+ spdlog::error("[{}] [{}:{}] IO error while reading from the socket: {}",
226
+ uuid::to_string(self->id_),
227
+ self->endpoint_.address().to_string(),
228
+ self->endpoint_.port(),
229
+ ec.message());
226
230
  return self->stop();
227
231
  }
228
232
 
@@ -235,10 +239,14 @@ class http_session : public std::enable_shared_from_this
235
239
  handler({}, std::move(self->parser_.response));
236
240
  }
237
241
  self->parser_.reset();
238
- return;
242
+ return self->stop();
239
243
  }
240
244
  return self->do_read();
241
245
  case http_parser::status::failure:
246
+ spdlog::error("[{}] [{}:{}] failed to parse HTTP response",
247
+ uuid::to_string(self->id_),
248
+ self->endpoint_.address().to_string(),
249
+ self->endpoint_.port());
242
250
  return self->stop();
243
251
  }
244
252
  });
@@ -263,7 +271,11 @@ class http_session : public std::enable_shared_from_this
263
271
  return;
264
272
  }
265
273
  if (ec) {
266
- spdlog::error("IO error while writing to the socket: {}", ec.message());
274
+ spdlog::error("[{}] [{}:{}] IO error while writing to the socket: {}",
275
+ uuid::to_string(self->id_),
276
+ self->endpoint_.address().to_string(),
277
+ self->endpoint_.port(),
278
+ ec.message());
267
279
  return self->stop();
268
280
  }
269
281
  self->writing_buffer_.clear();
@@ -301,4 +313,4 @@ class http_session : public std::enable_shared_from_this
301
313
  asio::ip::tcp::endpoint endpoint_{}; // connected endpoint
302
314
  asio::ip::tcp::resolver::results_type endpoints_;
303
315
  };
304
- } // namespace couchbase::io
316
+ } // namespace couchbase::io
@@ -790,9 +790,10 @@ class mcbp_session : public std::enable_shared_from_this
790
790
  return;
791
791
  }
792
792
  if (ec) {
793
- spdlog::error("[{}] [{}] IO error while reading from the socket: {}",
793
+ spdlog::error("[{}] [{}:{}] IO error while reading from the socket: {}",
794
794
  uuid::to_string(self->id_),
795
795
  self->endpoint_.address().to_string(),
796
+ self->endpoint_.port(),
796
797
  ec.message());
797
798
  return self->stop();
798
799
  }
@@ -23,7 +23,7 @@ struct mutation_token {
23
23
  uint64_t partition_uuid{ 0 };
24
24
  uint64_t sequence_number{ 0 };
25
25
  uint16_t partition_id{ 0 };
26
- std::string bucket_name {};
26
+ std::string bucket_name{};
27
27
  };
28
28
  } // namespace couchbase
29
29
 
@@ -38,6 +38,8 @@
38
38
 
39
39
  #include <operations/document_query.hxx>
40
40
  #include <operations/document_search.hxx>
41
+ #include <operations/document_analytics.hxx>
42
+ #include <operations/document_view.hxx>
41
43
 
42
44
  #include <operations/bucket_get_all.hxx>
43
45
  #include <operations/bucket_get.hxx>
@@ -69,4 +71,21 @@
69
71
  #include <operations/search_index_control_plan_freeze.hxx>
70
72
  #include <operations/search_index_analyze_document.hxx>
71
73
 
74
+ #include <operations/analytics_get_pending_mutations.hxx>
75
+ #include <operations/analytics_dataverse_create.hxx>
76
+ #include <operations/analytics_dataverse_drop.hxx>
77
+ #include <operations/analytics_dataset_create.hxx>
78
+ #include <operations/analytics_dataset_drop.hxx>
79
+ #include <operations/analytics_dataset_get_all.hxx>
80
+ #include <operations/analytics_index_get_all.hxx>
81
+ #include <operations/analytics_index_create.hxx>
82
+ #include <operations/analytics_index_drop.hxx>
83
+ #include <operations/analytics_link_connect.hxx>
84
+ #include <operations/analytics_link_disconnect.hxx>
85
+
86
+ #include <operations/view_index_get_all.hxx>
87
+ #include <operations/view_index_get.hxx>
88
+ #include <operations/view_index_drop.hxx>
89
+ #include <operations/view_index_upsert.hxx>
90
+
72
91
  #include <operations/command.hxx>
@@ -0,0 +1,117 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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 <tao/json.hpp>
21
+
22
+ #include <version.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+ struct analytics_dataset_create_response {
27
+ struct problem {
28
+ std::uint32_t code;
29
+ std::string message;
30
+ };
31
+
32
+ std::string client_context_id;
33
+ std::error_code ec;
34
+ std::string status{};
35
+ std::vector<problem> errors{};
36
+ };
37
+
38
+ struct analytics_dataset_create_request {
39
+ using response_type = analytics_dataset_create_response;
40
+ using encoded_request_type = io::http_request;
41
+ using encoded_response_type = io::http_response;
42
+
43
+ static const inline service_type type = service_type::analytics;
44
+
45
+ std::string client_context_id{ uuid::to_string(uuid::random()) };
46
+ std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
47
+
48
+ std::string dataverse_name{ "Default" };
49
+ std::string dataset_name;
50
+ std::string bucket_name;
51
+
52
+ std::optional<std::string> condition{};
53
+
54
+ bool ignore_if_exists{ false };
55
+
56
+ void encode_to(encoded_request_type& encoded)
57
+ {
58
+ std::string where_clause = condition ? fmt::format("WHERE {}", *condition) : "";
59
+ std::string if_not_exists_clause = ignore_if_exists ? "IF NOT EXISTS" : "";
60
+
61
+ tao::json::value body{
62
+ { "statement",
63
+ fmt::format(
64
+ "CREATE DATASET `{}`.`{}` ON `{}` {} {}", dataverse_name, dataset_name, bucket_name, where_clause, if_not_exists_clause) },
65
+ };
66
+ encoded.headers["content-type"] = "application/json";
67
+ encoded.method = "POST";
68
+ encoded.path = "/analytics/service";
69
+ encoded.body = tao::json::to_string(body);
70
+ }
71
+ };
72
+
73
+ analytics_dataset_create_response
74
+ make_response(std::error_code ec,
75
+ analytics_dataset_create_request& request,
76
+ analytics_dataset_create_request::encoded_response_type encoded)
77
+ {
78
+ analytics_dataset_create_response response{ request.client_context_id, ec };
79
+ if (!ec) {
80
+ auto payload = tao::json::from_string(encoded.body);
81
+ response.status = payload.at("status").get_string();
82
+
83
+ if (response.status != "success") {
84
+ bool dataset_exists = false;
85
+ bool link_not_found = false;
86
+
87
+ auto* errors = payload.find("errors");
88
+ if (errors != nullptr && errors->is_array()) {
89
+ for (const auto& error : errors->get_array()) {
90
+ analytics_dataset_create_response::problem err{
91
+ error.at("code").as<std::uint32_t>(),
92
+ error.at("msg").get_string(),
93
+ };
94
+ switch (err.code) {
95
+ case 24040: /* A dataset with name [string] already exists in dataverse [string] */
96
+ dataset_exists = true;
97
+ break;
98
+ case 24006: /* Link [string] does not exist */
99
+ link_not_found = true;
100
+ break;
101
+ }
102
+ response.errors.emplace_back(err);
103
+ }
104
+ }
105
+ if (dataset_exists) {
106
+ response.ec = std::make_error_code(error::analytics_errc::dataset_exists);
107
+ } else if (link_not_found) {
108
+ response.ec = std::make_error_code(error::analytics_errc::link_not_found);
109
+ } else {
110
+ response.ec = std::make_error_code(error::common_errc::internal_server_failure);
111
+ }
112
+ }
113
+ }
114
+ return response;
115
+ }
116
+
117
+ } // namespace couchbase::operations
@@ -0,0 +1,103 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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 <tao/json.hpp>
21
+
22
+ #include <version.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+ struct analytics_dataset_drop_response {
27
+ struct problem {
28
+ std::uint32_t code;
29
+ std::string message;
30
+ };
31
+
32
+ std::string client_context_id;
33
+ std::error_code ec;
34
+ std::string status{};
35
+ std::vector<problem> errors{};
36
+ };
37
+
38
+ struct analytics_dataset_drop_request {
39
+ using response_type = analytics_dataset_drop_response;
40
+ using encoded_request_type = io::http_request;
41
+ using encoded_response_type = io::http_response;
42
+
43
+ static const inline service_type type = service_type::analytics;
44
+
45
+ std::string client_context_id{ uuid::to_string(uuid::random()) };
46
+ std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
47
+
48
+ std::string dataverse_name{ "Default" };
49
+ std::string dataset_name;
50
+
51
+ bool ignore_if_does_not_exist{ false };
52
+
53
+ void encode_to(encoded_request_type& encoded)
54
+ {
55
+ std::string if_exists_clause = ignore_if_does_not_exist ? "IF EXISTS" : "";
56
+
57
+ tao::json::value body{
58
+ { "statement", fmt::format("DROP DATASET `{}`.`{}` {}", dataverse_name, dataset_name, if_exists_clause) },
59
+ };
60
+ encoded.headers["content-type"] = "application/json";
61
+ encoded.method = "POST";
62
+ encoded.path = "/analytics/service";
63
+ encoded.body = tao::json::to_string(body);
64
+ }
65
+ };
66
+
67
+ analytics_dataset_drop_response
68
+ make_response(std::error_code ec, analytics_dataset_drop_request& request, analytics_dataset_drop_request::encoded_response_type encoded)
69
+ {
70
+ analytics_dataset_drop_response response{ request.client_context_id, ec };
71
+ if (!ec) {
72
+ auto payload = tao::json::from_string(encoded.body);
73
+ response.status = payload.at("status").get_string();
74
+
75
+ if (response.status != "success") {
76
+ bool dataset_does_not_exist = false;
77
+
78
+ auto* errors = payload.find("errors");
79
+ if (errors != nullptr && errors->is_array()) {
80
+ for (const auto& error : errors->get_array()) {
81
+ analytics_dataset_drop_response::problem err{
82
+ error.at("code").as<std::uint32_t>(),
83
+ error.at("msg").get_string(),
84
+ };
85
+ switch (err.code) {
86
+ case 24025: /* Cannot find dataset with name [string] in dataverse [string] */
87
+ dataset_does_not_exist = true;
88
+ break;
89
+ }
90
+ response.errors.emplace_back(err);
91
+ }
92
+ }
93
+ if (dataset_does_not_exist) {
94
+ response.ec = std::make_error_code(error::analytics_errc::dataset_not_found);
95
+ } else {
96
+ response.ec = std::make_error_code(error::common_errc::internal_server_failure);
97
+ }
98
+ }
99
+ }
100
+ return response;
101
+ }
102
+
103
+ } // namespace couchbase::operations
@@ -0,0 +1,107 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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 <tao/json.hpp>
21
+
22
+ #include <version.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+ struct analytics_dataset_get_all_response {
27
+ struct dataset {
28
+ std::string name;
29
+ std::string dataverse_name;
30
+ std::string link_name;
31
+ std::string bucket_name;
32
+ };
33
+
34
+ struct problem {
35
+ std::uint32_t code;
36
+ std::string message;
37
+ };
38
+
39
+ std::string client_context_id;
40
+ std::error_code ec;
41
+ std::string status{};
42
+ std::vector<dataset> datasets{};
43
+ std::vector<problem> errors{};
44
+ };
45
+
46
+ struct analytics_dataset_get_all_request {
47
+ using response_type = analytics_dataset_get_all_response;
48
+ using encoded_request_type = io::http_request;
49
+ using encoded_response_type = io::http_response;
50
+
51
+ static const inline service_type type = service_type::analytics;
52
+
53
+ std::string client_context_id{ uuid::to_string(uuid::random()) };
54
+ std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
55
+
56
+ void encode_to(encoded_request_type& encoded)
57
+ {
58
+ tao::json::value body{
59
+ { "statement", "SELECT d.* FROM Metadata.`Dataset` d WHERE d.DataverseName <> \"Metadata\"" },
60
+ };
61
+ encoded.headers["content-type"] = "application/json";
62
+ encoded.method = "POST";
63
+ encoded.path = "/analytics/service";
64
+ encoded.body = tao::json::to_string(body);
65
+ }
66
+ };
67
+
68
+ analytics_dataset_get_all_response
69
+ make_response(std::error_code ec,
70
+ analytics_dataset_get_all_request& request,
71
+ analytics_dataset_get_all_request::encoded_response_type encoded)
72
+ {
73
+ analytics_dataset_get_all_response response{ request.client_context_id, ec };
74
+
75
+ if (!ec) {
76
+ auto payload = tao::json::from_string(encoded.body);
77
+ response.status = payload.at("status").get_string();
78
+ if (response.status == "success") {
79
+ auto* results = payload.find("results");
80
+ if (results != nullptr && results->is_array()) {
81
+ for (const auto& res : results->get_array()) {
82
+ analytics_dataset_get_all_response::dataset ds;
83
+ ds.name = res.at("DatasetName").get_string();
84
+ ds.dataverse_name = res.at("DataverseName").get_string();
85
+ ds.link_name = res.at("LinkName").get_string();
86
+ ds.bucket_name = res.at("BucketName").get_string();
87
+ response.datasets.emplace_back(ds);
88
+ }
89
+ }
90
+ } else {
91
+ auto* errors = payload.find("errors");
92
+ if (errors != nullptr && errors->is_array()) {
93
+ for (const auto& error : errors->get_array()) {
94
+ analytics_dataset_get_all_response::problem err{
95
+ error.at("code").as<std::uint32_t>(),
96
+ error.at("msg").get_string(),
97
+ };
98
+ response.errors.emplace_back(err);
99
+ }
100
+ }
101
+ response.ec = std::make_error_code(error::common_errc::internal_server_failure);
102
+ }
103
+ }
104
+ return response;
105
+ }
106
+
107
+ } // namespace couchbase::operations
@@ -0,0 +1,104 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 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 <tao/json.hpp>
21
+
22
+ #include <version.hxx>
23
+
24
+ namespace couchbase::operations
25
+ {
26
+ struct analytics_dataverse_create_response {
27
+ struct problem {
28
+ std::uint32_t code;
29
+ std::string message;
30
+ };
31
+
32
+ std::string client_context_id;
33
+ std::error_code ec;
34
+ std::string status{};
35
+ std::vector<problem> errors{};
36
+ };
37
+
38
+ struct analytics_dataverse_create_request {
39
+ using response_type = analytics_dataverse_create_response;
40
+ using encoded_request_type = io::http_request;
41
+ using encoded_response_type = io::http_response;
42
+
43
+ static const inline service_type type = service_type::analytics;
44
+
45
+ std::string client_context_id{ uuid::to_string(uuid::random()) };
46
+ std::chrono::milliseconds timeout{ timeout_defaults::management_timeout };
47
+
48
+ std::string dataverse_name;
49
+
50
+ bool ignore_if_exists{ false };
51
+
52
+ void encode_to(encoded_request_type& encoded)
53
+ {
54
+ std::string if_not_exists_clause = ignore_if_exists ? "IF NOT EXISTS" : "";
55
+
56
+ tao::json::value body{
57
+ { "statement", fmt::format("CREATE DATAVERSE `{}` {}", dataverse_name, if_not_exists_clause) },
58
+ };
59
+ encoded.headers["content-type"] = "application/json";
60
+ encoded.method = "POST";
61
+ encoded.path = "/analytics/service";
62
+ encoded.body = tao::json::to_string(body);
63
+ }
64
+ };
65
+
66
+ analytics_dataverse_create_response
67
+ make_response(std::error_code ec,
68
+ analytics_dataverse_create_request& request,
69
+ analytics_dataverse_create_request::encoded_response_type encoded)
70
+ {
71
+ analytics_dataverse_create_response response{ request.client_context_id, ec };
72
+ if (!ec) {
73
+ auto payload = tao::json::from_string(encoded.body);
74
+ response.status = payload.at("status").get_string();
75
+
76
+ if (response.status != "success") {
77
+ bool dataverse_exists = false;
78
+
79
+ auto* errors = payload.find("errors");
80
+ if (errors != nullptr && errors->is_array()) {
81
+ for (const auto& error : errors->get_array()) {
82
+ analytics_dataverse_create_response::problem err{
83
+ error.at("code").as<std::uint32_t>(),
84
+ error.at("msg").get_string(),
85
+ };
86
+ switch (err.code) {
87
+ case 24039: /* A dataverse with this name [string] already exists. */
88
+ dataverse_exists = true;
89
+ break;
90
+ }
91
+ response.errors.emplace_back(err);
92
+ }
93
+ }
94
+ if (dataverse_exists) {
95
+ response.ec = std::make_error_code(error::analytics_errc::dataverse_exists);
96
+ } else {
97
+ response.ec = std::make_error_code(error::common_errc::internal_server_failure);
98
+ }
99
+ }
100
+ }
101
+ return response;
102
+ }
103
+
104
+ } // namespace couchbase::operations