couchbase 3.0.0.alpha.3-universal-darwin-19 → 3.0.0.alpha.4-universal-darwin-19
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.
- checksums.yaml +4 -4
- data/.github/workflows/tests-6.0.3.yml +4 -1
- data/.github/workflows/tests-dev-preview.yml +4 -1
- data/.github/workflows/tests.yml +4 -1
- data/README.md +1 -1
- data/bin/check-cluster +31 -0
- data/bin/init-cluster +16 -4
- data/examples/analytics.rb +221 -0
- data/examples/managing_analytics_indexes.rb +72 -0
- data/examples/managing_view_indexes.rb +54 -0
- data/examples/search_with_consistency.rb +84 -0
- data/examples/view.rb +50 -0
- data/ext/.clang-tidy +1 -0
- data/ext/build_version.hxx.in +1 -1
- data/ext/couchbase/bucket.hxx +0 -1
- data/ext/couchbase/couchbase.cxx +1421 -55
- data/ext/couchbase/io/dns_client.hxx +215 -0
- data/ext/couchbase/io/dns_codec.hxx +207 -0
- data/ext/couchbase/io/dns_config.hxx +116 -0
- data/ext/couchbase/io/dns_message.hxx +558 -0
- data/ext/couchbase/io/http_session.hxx +16 -4
- data/ext/couchbase/io/mcbp_session.hxx +2 -1
- data/ext/couchbase/mutation_token.hxx +1 -1
- data/ext/couchbase/operations.hxx +19 -0
- data/ext/couchbase/operations/analytics_dataset_create.hxx +117 -0
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +103 -0
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +107 -0
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +104 -0
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +104 -0
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +91 -0
- data/ext/couchbase/operations/analytics_index_create.hxx +128 -0
- data/ext/couchbase/operations/analytics_index_drop.hxx +110 -0
- data/ext/couchbase/operations/analytics_index_get_all.hxx +106 -0
- data/ext/couchbase/operations/analytics_link_connect.hxx +102 -0
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +101 -0
- data/ext/couchbase/operations/design_document.hxx +59 -0
- data/ext/couchbase/operations/document_analytics.hxx +293 -0
- data/ext/couchbase/operations/document_query.hxx +2 -2
- data/ext/couchbase/operations/document_search.hxx +19 -1
- data/ext/couchbase/operations/document_view.hxx +227 -0
- data/ext/couchbase/operations/search_index.hxx +17 -0
- data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -1
- data/ext/couchbase/operations/view_index_drop.hxx +67 -0
- data/ext/couchbase/operations/view_index_get.hxx +90 -0
- data/ext/couchbase/operations/view_index_get_all.hxx +125 -0
- data/ext/couchbase/operations/view_index_upsert.hxx +87 -0
- data/ext/couchbase/service_type.hxx +38 -1
- data/ext/couchbase/timeout_defaults.hxx +3 -1
- data/ext/couchbase/utils/connection_string.hxx +231 -0
- data/ext/couchbase/version.hxx +1 -1
- data/ext/test/main.cxx +3 -12
- data/lib/couchbase/analytics_options.rb +165 -0
- data/lib/couchbase/bucket.rb +49 -0
- data/lib/couchbase/cluster.rb +46 -207
- data/lib/couchbase/management/analytics_index_manager.rb +138 -24
- data/lib/couchbase/management/view_index_manager.rb +63 -10
- data/lib/couchbase/query_options.rb +219 -0
- data/lib/couchbase/search_options.rb +6 -6
- data/lib/couchbase/version.rb +1 -1
- data/lib/couchbase/view_options.rb +155 -0
- metadata +34 -2
@@ -0,0 +1,102 @@
|
|
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_link_connect_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_link_connect_request {
|
39
|
+
using response_type = analytics_link_connect_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 link_name;
|
50
|
+
bool force{ false };
|
51
|
+
|
52
|
+
void encode_to(encoded_request_type& encoded)
|
53
|
+
{
|
54
|
+
std::string with_clause = force ? "WITH {\"force\": true}" : "";
|
55
|
+
|
56
|
+
tao::json::value body{
|
57
|
+
{ "statement", fmt::format("CONNECT LINK `{}`.`{}` {}", dataverse_name, link_name, with_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_link_connect_response
|
67
|
+
make_response(std::error_code ec, analytics_link_connect_request& request, analytics_link_connect_request::encoded_response_type encoded)
|
68
|
+
{
|
69
|
+
analytics_link_connect_response response{ request.client_context_id, ec };
|
70
|
+
if (!ec) {
|
71
|
+
auto payload = tao::json::from_string(encoded.body);
|
72
|
+
response.status = payload.at("status").get_string();
|
73
|
+
|
74
|
+
if (response.status != "success") {
|
75
|
+
bool link_not_found = false;
|
76
|
+
|
77
|
+
auto* errors = payload.find("errors");
|
78
|
+
if (errors != nullptr && errors->is_array()) {
|
79
|
+
for (const auto& error : errors->get_array()) {
|
80
|
+
analytics_link_connect_response::problem err{
|
81
|
+
error.at("code").as<std::uint32_t>(),
|
82
|
+
error.at("msg").get_string(),
|
83
|
+
};
|
84
|
+
switch (err.code) {
|
85
|
+
case 24006: /* Link [string] does not exist */
|
86
|
+
link_not_found = true;
|
87
|
+
break;
|
88
|
+
}
|
89
|
+
response.errors.emplace_back(err);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
if (link_not_found) {
|
93
|
+
response.ec = std::make_error_code(error::analytics_errc::link_not_found);
|
94
|
+
} else {
|
95
|
+
response.ec = std::make_error_code(error::common_errc::internal_server_failure);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
return response;
|
100
|
+
}
|
101
|
+
|
102
|
+
} // namespace couchbase::operations
|
@@ -0,0 +1,101 @@
|
|
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_link_disconnect_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_link_disconnect_request {
|
39
|
+
using response_type = analytics_link_disconnect_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 link_name;
|
50
|
+
|
51
|
+
void encode_to(encoded_request_type& encoded)
|
52
|
+
{
|
53
|
+
tao::json::value body{
|
54
|
+
{ "statement", fmt::format("DISCONNECT LINK `{}`.`{}`", dataverse_name, link_name) },
|
55
|
+
};
|
56
|
+
encoded.headers["content-type"] = "application/json";
|
57
|
+
encoded.method = "POST";
|
58
|
+
encoded.path = "/analytics/service";
|
59
|
+
encoded.body = tao::json::to_string(body);
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
analytics_link_disconnect_response
|
64
|
+
make_response(std::error_code ec,
|
65
|
+
analytics_link_disconnect_request& request,
|
66
|
+
analytics_link_disconnect_request::encoded_response_type encoded)
|
67
|
+
{
|
68
|
+
analytics_link_disconnect_response response{ request.client_context_id, ec };
|
69
|
+
if (!ec) {
|
70
|
+
auto payload = tao::json::from_string(encoded.body);
|
71
|
+
response.status = payload.at("status").get_string();
|
72
|
+
|
73
|
+
if (response.status != "success") {
|
74
|
+
bool link_not_found = false;
|
75
|
+
|
76
|
+
auto* errors = payload.find("errors");
|
77
|
+
if (errors != nullptr && errors->is_array()) {
|
78
|
+
for (const auto& error : errors->get_array()) {
|
79
|
+
analytics_link_disconnect_response::problem err{
|
80
|
+
error.at("code").as<std::uint32_t>(),
|
81
|
+
error.at("msg").get_string(),
|
82
|
+
};
|
83
|
+
switch (err.code) {
|
84
|
+
case 24006: /* Link [string] does not exist */
|
85
|
+
link_not_found = true;
|
86
|
+
break;
|
87
|
+
}
|
88
|
+
response.errors.emplace_back(err);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
if (link_not_found) {
|
92
|
+
response.ec = std::make_error_code(error::analytics_errc::link_not_found);
|
93
|
+
} else {
|
94
|
+
response.ec = std::make_error_code(error::common_errc::internal_server_failure);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
98
|
+
return response;
|
99
|
+
}
|
100
|
+
|
101
|
+
} // namespace couchbase::operations
|
@@ -0,0 +1,59 @@
|
|
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
|
+
namespace couchbase::operations
|
21
|
+
{
|
22
|
+
struct design_document {
|
23
|
+
enum class name_space {
|
24
|
+
development,
|
25
|
+
production,
|
26
|
+
};
|
27
|
+
|
28
|
+
struct view {
|
29
|
+
std::string name;
|
30
|
+
std::optional<std::string> map;
|
31
|
+
std::optional<std::string> reduce;
|
32
|
+
};
|
33
|
+
|
34
|
+
std::string rev;
|
35
|
+
std::string name;
|
36
|
+
design_document::name_space ns;
|
37
|
+
std::map<std::string, view> views;
|
38
|
+
};
|
39
|
+
|
40
|
+
} // namespace couchbase::operations
|
41
|
+
|
42
|
+
template<>
|
43
|
+
struct fmt::formatter<couchbase::operations::design_document::name_space> : formatter<string_view> {
|
44
|
+
template<typename FormatContext>
|
45
|
+
auto format(couchbase::operations::design_document::name_space ns, FormatContext& ctx)
|
46
|
+
{
|
47
|
+
string_view name = "unknown";
|
48
|
+
switch (ns) {
|
49
|
+
case couchbase::operations::design_document::name_space::development:
|
50
|
+
name = "development";
|
51
|
+
break;
|
52
|
+
|
53
|
+
case couchbase::operations::design_document::name_space::production:
|
54
|
+
name = "production";
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
return formatter<string_view>::format(name, ctx);
|
58
|
+
}
|
59
|
+
};
|
@@ -0,0 +1,293 @@
|
|
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 <gsl/gsl>
|
21
|
+
|
22
|
+
#include <spdlog/spdlog.h>
|
23
|
+
|
24
|
+
#include <tao/json.hpp>
|
25
|
+
|
26
|
+
#include <version.hxx>
|
27
|
+
|
28
|
+
#include <errors.hxx>
|
29
|
+
#include <mutation_token.hxx>
|
30
|
+
#include <service_type.hxx>
|
31
|
+
#include <platform/uuid.h>
|
32
|
+
#include <timeout_defaults.hxx>
|
33
|
+
#include <io/http_message.hxx>
|
34
|
+
|
35
|
+
namespace couchbase::operations
|
36
|
+
{
|
37
|
+
struct analytics_response_payload {
|
38
|
+
struct analytics_metrics {
|
39
|
+
std::string elapsed_time;
|
40
|
+
std::string execution_time;
|
41
|
+
std::uint64_t result_count;
|
42
|
+
std::uint64_t result_size;
|
43
|
+
std::optional<std::uint64_t> sort_count;
|
44
|
+
std::optional<std::uint64_t> mutation_count;
|
45
|
+
std::optional<std::uint64_t> error_count;
|
46
|
+
std::optional<std::uint64_t> warning_count;
|
47
|
+
};
|
48
|
+
|
49
|
+
struct analytics_problem {
|
50
|
+
std::uint64_t code;
|
51
|
+
std::string message;
|
52
|
+
};
|
53
|
+
|
54
|
+
struct analytics_meta_data {
|
55
|
+
std::string request_id;
|
56
|
+
std::string client_context_id;
|
57
|
+
std::string status;
|
58
|
+
analytics_metrics metrics;
|
59
|
+
std::optional<std::string> signature;
|
60
|
+
std::optional<std::string> profile;
|
61
|
+
std::optional<std::vector<analytics_problem>> warnings;
|
62
|
+
std::optional<std::vector<analytics_problem>> errors;
|
63
|
+
};
|
64
|
+
|
65
|
+
analytics_meta_data meta_data{};
|
66
|
+
std::vector<std::string> rows{};
|
67
|
+
};
|
68
|
+
} // namespace couchbase::operations
|
69
|
+
|
70
|
+
namespace tao::json
|
71
|
+
{
|
72
|
+
template<>
|
73
|
+
struct traits<couchbase::operations::analytics_response_payload> {
|
74
|
+
template<template<typename...> class Traits>
|
75
|
+
static couchbase::operations::analytics_response_payload as(const tao::json::basic_value<Traits>& v)
|
76
|
+
{
|
77
|
+
couchbase::operations::analytics_response_payload result;
|
78
|
+
result.meta_data.request_id = v.at("requestID").get_string();
|
79
|
+
result.meta_data.client_context_id = v.at("clientContextID").get_string();
|
80
|
+
result.meta_data.status = v.at("status").get_string();
|
81
|
+
const auto s = v.find("signature");
|
82
|
+
if (s != nullptr) {
|
83
|
+
result.meta_data.signature = tao::json::to_string(*s);
|
84
|
+
}
|
85
|
+
|
86
|
+
const auto p = v.find("profile");
|
87
|
+
if (p != nullptr) {
|
88
|
+
result.meta_data.profile = tao::json::to_string(*p);
|
89
|
+
}
|
90
|
+
|
91
|
+
const auto m = v.find("metrics");
|
92
|
+
if (m != nullptr) {
|
93
|
+
result.meta_data.metrics.result_count = m->at("resultCount").get_unsigned();
|
94
|
+
result.meta_data.metrics.result_size = m->at("resultSize").get_unsigned();
|
95
|
+
result.meta_data.metrics.elapsed_time = m->at("elapsedTime").get_string();
|
96
|
+
result.meta_data.metrics.execution_time = m->at("executionTime").get_string();
|
97
|
+
result.meta_data.metrics.sort_count = m->template optional<std::uint64_t>("sortCount");
|
98
|
+
result.meta_data.metrics.mutation_count = m->template optional<std::uint64_t>("mutationCount");
|
99
|
+
result.meta_data.metrics.error_count = m->template optional<std::uint64_t>("errorCount");
|
100
|
+
result.meta_data.metrics.warning_count = m->template optional<std::uint64_t>("warningCount");
|
101
|
+
}
|
102
|
+
|
103
|
+
const auto e = v.find("errors");
|
104
|
+
if (e != nullptr) {
|
105
|
+
std::vector<couchbase::operations::analytics_response_payload::analytics_problem> problems{};
|
106
|
+
for (auto& err : e->get_array()) {
|
107
|
+
couchbase::operations::analytics_response_payload::analytics_problem problem;
|
108
|
+
problem.code = err.at("code").get_unsigned();
|
109
|
+
problem.message = err.at("msg").get_string();
|
110
|
+
problems.emplace_back(problem);
|
111
|
+
}
|
112
|
+
result.meta_data.errors.emplace(problems);
|
113
|
+
}
|
114
|
+
|
115
|
+
const auto w = v.find("warnings");
|
116
|
+
if (w != nullptr) {
|
117
|
+
std::vector<couchbase::operations::analytics_response_payload::analytics_problem> problems{};
|
118
|
+
for (auto& warn : w->get_array()) {
|
119
|
+
couchbase::operations::analytics_response_payload::analytics_problem problem;
|
120
|
+
problem.code = warn.at("code").get_unsigned();
|
121
|
+
problem.message = warn.at("msg").get_string();
|
122
|
+
problems.emplace_back(problem);
|
123
|
+
}
|
124
|
+
result.meta_data.warnings.emplace(problems);
|
125
|
+
}
|
126
|
+
const auto r = v.find("results");
|
127
|
+
if (r != nullptr) {
|
128
|
+
result.rows.reserve(result.meta_data.metrics.result_count);
|
129
|
+
for (auto& row : r->get_array()) {
|
130
|
+
result.rows.emplace_back(tao::json::to_string(row));
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
return result;
|
135
|
+
}
|
136
|
+
};
|
137
|
+
} // namespace tao::json
|
138
|
+
|
139
|
+
namespace couchbase::operations
|
140
|
+
{
|
141
|
+
struct analytics_response {
|
142
|
+
std::string client_context_id;
|
143
|
+
std::error_code ec;
|
144
|
+
analytics_response_payload payload{};
|
145
|
+
};
|
146
|
+
|
147
|
+
struct analytics_request {
|
148
|
+
using response_type = analytics_response;
|
149
|
+
using encoded_request_type = io::http_request;
|
150
|
+
using encoded_response_type = io::http_response;
|
151
|
+
|
152
|
+
enum class scan_consistency_type { not_bounded, request_plus };
|
153
|
+
|
154
|
+
static const inline service_type type = service_type::analytics;
|
155
|
+
|
156
|
+
std::chrono::milliseconds timeout{ timeout_defaults::analytics_timeout };
|
157
|
+
std::string statement;
|
158
|
+
std::string client_context_id{ uuid::to_string(uuid::random()) };
|
159
|
+
|
160
|
+
bool readonly{ false };
|
161
|
+
bool priority{ false };
|
162
|
+
|
163
|
+
std::optional<scan_consistency_type> scan_consistency{};
|
164
|
+
std::optional<std::uint64_t> scan_wait{};
|
165
|
+
|
166
|
+
std::map<std::string, tao::json::value> raw{};
|
167
|
+
std::vector<tao::json::value> positional_parameters{};
|
168
|
+
std::map<std::string, tao::json::value> named_parameters{};
|
169
|
+
|
170
|
+
void encode_to(encoded_request_type& encoded)
|
171
|
+
{
|
172
|
+
encoded.headers["content-type"] = "application/json";
|
173
|
+
if (priority) {
|
174
|
+
encoded.headers["analytics-priority"] = "-1";
|
175
|
+
}
|
176
|
+
tao::json::value body{ { "statement", statement },
|
177
|
+
{ "client_context_id", client_context_id },
|
178
|
+
{ "timeout", fmt::format("{}ms", timeout.count()) } };
|
179
|
+
if (positional_parameters.empty()) {
|
180
|
+
for (auto& param : named_parameters) {
|
181
|
+
Expects(param.first.empty() == false);
|
182
|
+
std::string key = param.first;
|
183
|
+
if (key[0] != '$') {
|
184
|
+
key.insert(key.begin(), '$');
|
185
|
+
}
|
186
|
+
body[key] = param.second;
|
187
|
+
}
|
188
|
+
} else {
|
189
|
+
body["args"] = positional_parameters;
|
190
|
+
}
|
191
|
+
if (readonly) {
|
192
|
+
body["readonly"] = true;
|
193
|
+
}
|
194
|
+
if (scan_consistency) {
|
195
|
+
switch (scan_consistency.value()) {
|
196
|
+
case scan_consistency_type::not_bounded:
|
197
|
+
body["scan_consistency"] = "not_bounded";
|
198
|
+
break;
|
199
|
+
case scan_consistency_type::request_plus:
|
200
|
+
body["scan_consistency"] = "request_plus";
|
201
|
+
break;
|
202
|
+
}
|
203
|
+
if (scan_wait) {
|
204
|
+
body["scan_wait"] = fmt::format("{}ms", scan_wait.value());
|
205
|
+
}
|
206
|
+
}
|
207
|
+
for (auto& param : raw) {
|
208
|
+
body[param.first] = param.second;
|
209
|
+
}
|
210
|
+
encoded.method = "POST";
|
211
|
+
encoded.path = "/query/service";
|
212
|
+
encoded.body = tao::json::to_string(body);
|
213
|
+
spdlog::trace("analytics request: {}", encoded.body);
|
214
|
+
}
|
215
|
+
};
|
216
|
+
|
217
|
+
analytics_response
|
218
|
+
make_response(std::error_code ec, analytics_request& request, analytics_request::encoded_response_type encoded)
|
219
|
+
{
|
220
|
+
analytics_response response{ request.client_context_id, ec };
|
221
|
+
if (!ec) {
|
222
|
+
spdlog::trace("analytics response: {}", encoded.body);
|
223
|
+
response.payload = tao::json::from_string(encoded.body).as<analytics_response_payload>();
|
224
|
+
Expects(response.payload.meta_data.client_context_id == request.client_context_id);
|
225
|
+
if (response.payload.meta_data.status != "success") {
|
226
|
+
bool server_timeout = false;
|
227
|
+
bool job_queue_is_full = false;
|
228
|
+
bool dataset_not_found = false;
|
229
|
+
bool dataverse_not_found = false;
|
230
|
+
bool dataset_exists = false;
|
231
|
+
bool dataverse_exists = false;
|
232
|
+
bool link_not_found = false;
|
233
|
+
bool compilation_failure = false;
|
234
|
+
|
235
|
+
if (response.payload.meta_data.errors) {
|
236
|
+
for (const auto& error : *response.payload.meta_data.errors) {
|
237
|
+
switch (error.code) {
|
238
|
+
case 21002: /* Request timed out and will be cancelled */
|
239
|
+
server_timeout = true;
|
240
|
+
break;
|
241
|
+
case 23007: /* Job queue is full with [string] jobs */
|
242
|
+
job_queue_is_full = true;
|
243
|
+
break;
|
244
|
+
case 24044: /* Cannot find dataset [string] because there is no dataverse declared, nor an alias with name [string]!
|
245
|
+
*/
|
246
|
+
case 24045: /* Cannot find dataset [string] in dataverse [string] nor an alias with name [string]! */
|
247
|
+
case 24025: /* Cannot find dataset with name [string] in dataverse [string] */
|
248
|
+
dataset_not_found = true;
|
249
|
+
break;
|
250
|
+
case 24034: /* Cannot find dataverse with name [string] */
|
251
|
+
dataverse_not_found = true;
|
252
|
+
break;
|
253
|
+
case 24040: /* A dataset with name [string] already exists in dataverse [string] */
|
254
|
+
dataset_exists = true;
|
255
|
+
break;
|
256
|
+
case 24039: /* A dataverse with this name [string] already exists. */
|
257
|
+
dataverse_exists = true;
|
258
|
+
break;
|
259
|
+
case 24006: /* Link [string] does not exist | Link [string] does not exist */
|
260
|
+
link_not_found = true;
|
261
|
+
break;
|
262
|
+
default:
|
263
|
+
if (error.code >= 24000 && error.code < 25000) {
|
264
|
+
compilation_failure = true;
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}
|
268
|
+
}
|
269
|
+
if (compilation_failure) {
|
270
|
+
response.ec = std::make_error_code(error::analytics_errc::compilation_failure);
|
271
|
+
} else if (link_not_found) {
|
272
|
+
response.ec = std::make_error_code(error::analytics_errc::link_not_found);
|
273
|
+
} else if (dataset_not_found) {
|
274
|
+
response.ec = std::make_error_code(error::analytics_errc::dataset_not_found);
|
275
|
+
} else if (dataverse_not_found) {
|
276
|
+
response.ec = std::make_error_code(error::analytics_errc::dataverse_not_found);
|
277
|
+
} else if (server_timeout) {
|
278
|
+
response.ec = std::make_error_code(error::common_errc::unambiguous_timeout);
|
279
|
+
} else if (dataset_exists) {
|
280
|
+
response.ec = std::make_error_code(error::analytics_errc::dataset_exists);
|
281
|
+
} else if (dataverse_exists) {
|
282
|
+
response.ec = std::make_error_code(error::analytics_errc::dataverse_exists);
|
283
|
+
} else if (job_queue_is_full) {
|
284
|
+
response.ec = std::make_error_code(error::analytics_errc::job_queue_full);
|
285
|
+
} else {
|
286
|
+
response.ec = std::make_error_code(error::common_errc::internal_server_failure);
|
287
|
+
}
|
288
|
+
}
|
289
|
+
}
|
290
|
+
return response;
|
291
|
+
}
|
292
|
+
|
293
|
+
} // namespace couchbase::operations
|