couchbase 3.2.0 → 3.2.4
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.
- package/README.md +24 -18
- package/binding.gyp +88 -85
- package/deps/lcb/CMakeLists.txt +1 -1
- package/deps/lcb/CONTRIBUTING.md +1 -1
- package/deps/lcb/README.markdown +2 -2
- package/deps/lcb/RELEASE_NOTES.markdown +99 -14
- package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
- package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
- package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -7
- package/deps/lcb/doc/Doxyfile +1 -1
- package/deps/lcb/example/CMakeLists.txt +4 -4
- package/deps/lcb/example/libuvdirect/main.c +39 -12
- package/deps/lcb/example/minimal/durability.cc +149 -0
- package/deps/lcb/example/minimal/query.c +11 -9
- package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
- package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
- package/deps/lcb/include/libcouchbase/couchbase.h +80 -5
- package/deps/lcb/include/libcouchbase/error.h +2 -0
- package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
- package/deps/lcb/include/libcouchbase/tracing.h +2 -2
- package/deps/lcb/include/memcached/protocol_binary.h +21 -0
- package/deps/lcb/libcouchbase.gyp +347 -349
- package/deps/lcb/packaging/deb/control +1 -1
- package/deps/lcb/src/analytics/analytics_handle.cc +13 -5
- package/deps/lcb/src/analytics/analytics_handle.hh +29 -0
- package/deps/lcb/src/bootstrap.cc +6 -3
- package/deps/lcb/src/capi/cmd_analytics.cc +12 -1
- package/deps/lcb/src/capi/cmd_analytics.hh +30 -0
- package/deps/lcb/src/capi/cmd_counter.hh +23 -0
- package/deps/lcb/src/capi/cmd_exists.hh +24 -1
- package/deps/lcb/src/capi/cmd_get.hh +22 -0
- package/deps/lcb/src/capi/cmd_get_replica.hh +23 -0
- package/deps/lcb/src/capi/cmd_http.hh +7 -0
- package/deps/lcb/src/capi/cmd_query.cc +11 -1
- package/deps/lcb/src/capi/cmd_query.hh +31 -0
- package/deps/lcb/src/capi/cmd_remove.hh +23 -0
- package/deps/lcb/src/capi/cmd_search.cc +6 -0
- package/deps/lcb/src/capi/cmd_search.hh +23 -0
- package/deps/lcb/src/capi/cmd_store.hh +33 -21
- package/deps/lcb/src/capi/cmd_subdoc.hh +35 -0
- package/deps/lcb/src/capi/cmd_touch.hh +23 -0
- package/deps/lcb/src/capi/cmd_unlock.hh +23 -0
- package/deps/lcb/src/capi/cmd_view.hh +6 -0
- package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
- package/deps/lcb/src/cntl.cc +45 -11
- package/deps/lcb/src/crypto.cc +2 -2
- package/deps/lcb/src/dns-srv.cc +5 -3
- package/deps/lcb/src/errmap.cc +5 -9
- package/deps/lcb/src/errmap.h +7 -3
- package/deps/lcb/src/handler.cc +24 -18
- package/deps/lcb/src/hostlist.h +2 -2
- package/deps/lcb/src/http/http-priv.h +2 -2
- package/deps/lcb/src/http/http.cc +5 -2
- package/deps/lcb/src/instance.cc +20 -11
- package/deps/lcb/src/internal.h +9 -0
- package/deps/lcb/src/lcbio/connect.cc +14 -2
- package/deps/lcb/src/lcbio/connect.h +2 -2
- package/deps/lcb/src/lcbio/ctx.cc +4 -2
- package/deps/lcb/src/lcbio/ioutils.cc +9 -10
- package/deps/lcb/src/lcbio/manager.cc +1 -1
- package/deps/lcb/src/mcserver/mcserver.cc +9 -6
- package/deps/lcb/src/mcserver/negotiate.cc +39 -17
- package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
- package/deps/lcb/src/n1ql/query_handle.cc +41 -19
- package/deps/lcb/src/n1ql/query_handle.hh +28 -1
- package/deps/lcb/src/operations/counter.cc +18 -5
- package/deps/lcb/src/operations/exists.cc +25 -4
- package/deps/lcb/src/operations/get.cc +39 -19
- package/deps/lcb/src/operations/get_replica.cc +28 -8
- package/deps/lcb/src/operations/observe.cc +1 -1
- package/deps/lcb/src/operations/ping.cc +8 -8
- package/deps/lcb/src/operations/pktfwd.cc +2 -1
- package/deps/lcb/src/operations/remove.cc +39 -22
- package/deps/lcb/src/operations/store.cc +18 -5
- package/deps/lcb/src/operations/subdoc.cc +18 -6
- package/deps/lcb/src/operations/touch.cc +34 -16
- package/deps/lcb/src/operations/unlock.cc +24 -5
- package/deps/lcb/src/packetutils.h +3 -2
- package/deps/lcb/src/retryq.cc +24 -5
- package/deps/lcb/src/search/search.cc +1 -0
- package/deps/lcb/src/search/search_handle.cc +30 -8
- package/deps/lcb/src/search/search_handle.hh +29 -0
- package/deps/lcb/src/settings.cc +1 -1
- package/deps/lcb/src/ssl/ssl_common.c +6 -7
- package/deps/lcb/src/tracing/span.cc +47 -14
- package/deps/lcb/src/tracing/tracer.cc +11 -2
- package/deps/lcb/src/tracing/tracing-internal.h +105 -93
- package/deps/lcb/src/utilities.cc +43 -0
- package/deps/lcb/src/utilities.h +53 -0
- package/deps/lcb/src/vbucket/vbucket.c +34 -33
- package/deps/lcb/src/views/view_handle.cc +13 -5
- package/deps/lcb/src/views/view_handle.hh +29 -0
- package/deps/lcb/tests/CMakeLists.txt +21 -0
- package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
- package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
- package/deps/lcb/tests/basic/t_n1qlstrings.cc +73 -0
- package/deps/lcb/tests/iotests/mock-environment.cc +30 -1
- package/deps/lcb/tests/iotests/mock-environment.h +49 -0
- package/deps/lcb/tests/iotests/mock-unit-test.cc +104 -6
- package/deps/lcb/tests/iotests/mock-unit-test.h +34 -0
- package/deps/lcb/tests/iotests/t_collections.cc +1 -1
- package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
- package/deps/lcb/tests/iotests/t_get.cc +109 -7
- package/deps/lcb/tests/iotests/t_http.cc +9 -4
- package/deps/lcb/tests/iotests/t_lock.cc +18 -0
- package/deps/lcb/tests/iotests/t_mutate.cc +157 -63
- package/deps/lcb/tests/iotests/t_n1ql.cc +330 -33
- package/deps/lcb/tests/iotests/t_views.cc +1 -0
- package/deps/lcb/tests/iotests/testutil.cc +168 -0
- package/deps/lcb/tests/iotests/testutil.h +116 -0
- package/deps/lcb/tests/mocksupport/procutil.c +32 -28
- package/deps/lcb/tests/mocksupport/server.c +0 -1
- package/deps/lcb/tests/mocksupport/timeout.c +2 -2
- package/deps/lcb/tools/cbc.cc +7 -0
- package/dist/analyticsindexmanager.js +512 -524
- package/dist/binding.d.ts +3 -0
- package/dist/bindingutilities.js +4 -0
- package/dist/bucket.js +1 -1
- package/dist/bucketmanager.d.ts +31 -1
- package/dist/bucketmanager.js +194 -186
- package/dist/cluster.d.ts +7 -0
- package/dist/cluster.js +48 -38
- package/dist/collection.js +11 -17
- package/dist/collectionmanager.js +181 -197
- package/dist/connection.d.ts +3 -1
- package/dist/connection.js +27 -16
- package/dist/couchbase.d.ts +1 -0
- package/dist/couchbase.js +3 -13
- package/dist/datastructures.js +239 -310
- package/dist/diagnosticsexecutor.js +70 -85
- package/dist/errors.d.ts +70 -0
- package/dist/errors.js +96 -2
- package/dist/eventingfunctionmanager.d.ts +804 -0
- package/dist/eventingfunctionmanager.js +993 -0
- package/dist/httpexecutor.d.ts +2 -1
- package/dist/httpexecutor.js +30 -37
- package/dist/queryindexmanager.js +240 -266
- package/dist/scope.js +10 -4
- package/dist/sdspecs.d.ts +1 -1
- package/dist/searchexecutor.js +3 -0
- package/dist/searchindexmanager.js +240 -271
- package/dist/searchquery.d.ts +17 -0
- package/dist/searchquery.js +22 -1
- package/dist/searchtypes.d.ts +7 -2
- package/dist/searchtypes.js +2 -2
- package/dist/usermanager.js +251 -264
- package/dist/utilities.d.ts +2 -0
- package/dist/utilities.js +7 -2
- package/dist/viewexecutor.js +1 -1
- package/dist/viewindexmanager.js +131 -150
- package/package.json +1 -1
- package/src/addondata.cpp +58 -0
- package/src/addondata.h +40 -0
- package/src/binding.cpp +3 -1
- package/src/cas.h +2 -2
- package/src/connection.cpp +25 -178
- package/src/connection.h +8 -65
- package/src/connection_ops.cpp +57 -34
- package/src/constants.cpp +3 -0
- package/src/instance.cpp +235 -0
- package/src/instance.h +102 -0
- package/src/{connection_callbacks.cpp → instance_callbacks.cpp} +34 -34
- package/src/logger.cpp +11 -1
- package/src/logger.h +3 -0
- package/src/metrics.cpp +10 -0
- package/src/metrics.h +3 -0
- package/src/mutationtoken.h +2 -2
- package/src/opbuilder.h +13 -15
- package/src/respreader.cpp +1 -0
- package/src/respreader.h +6 -4
- package/src/tracespan.h +11 -11
- package/src/tracing.cpp +11 -0
- package/src/tracing.h +3 -0
- package/src/valueparser.h +5 -0
- package/deps/lcb/example/observe/durability.c +0 -110
|
@@ -165,6 +165,8 @@ class QueryUnitTest : public MockUnitTest
|
|
|
165
165
|
|
|
166
166
|
TEST_F(QueryUnitTest, testSimple)
|
|
167
167
|
{
|
|
168
|
+
MockEnvironment *mock = MockEnvironment::getInstance();
|
|
169
|
+
tracing_guard use_tracing;
|
|
168
170
|
lcb_INSTANCE *instance;
|
|
169
171
|
HandleWrap hw;
|
|
170
172
|
if (!createQueryConnection(hw, &instance)) {
|
|
@@ -172,12 +174,26 @@ TEST_F(QueryUnitTest, testSimple)
|
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
N1QLResult res;
|
|
175
|
-
|
|
177
|
+
const char *query = "SELECT mockrow";
|
|
178
|
+
makeCommand(query);
|
|
179
|
+
|
|
180
|
+
const char *context_id = "context_id";
|
|
181
|
+
lcb_cmdquery_client_context_id(cmd, context_id, strlen(context_id));
|
|
182
|
+
|
|
176
183
|
lcb_STATUS rc = lcb_query(instance, &res, cmd);
|
|
177
184
|
ASSERT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
178
185
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
179
186
|
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc);
|
|
180
187
|
ASSERT_EQ(1, res.rows.size());
|
|
188
|
+
|
|
189
|
+
auto spans = mock->getTracer().spans;
|
|
190
|
+
ASSERT_EQ(1, spans.size());
|
|
191
|
+
auto span = spans[0];
|
|
192
|
+
HTTPSpanAssertions assertions;
|
|
193
|
+
assertions.statement = query;
|
|
194
|
+
assertions.operation_id = context_id;
|
|
195
|
+
assertions.service = "query";
|
|
196
|
+
assert_http_span(span, "query", assertions);
|
|
181
197
|
}
|
|
182
198
|
|
|
183
199
|
TEST_F(QueryUnitTest, testQueryError)
|
|
@@ -365,39 +381,286 @@ TEST_F(QueryUnitTest, testClusterwide)
|
|
|
365
381
|
ASSERT_FALSE(res.called);
|
|
366
382
|
}
|
|
367
383
|
|
|
384
|
+
struct upsert_result {
|
|
385
|
+
bool invoked{false};
|
|
386
|
+
lcb_STATUS rc{LCB_ERR_GENERIC};
|
|
387
|
+
std::string id{};
|
|
388
|
+
std::uint64_t cas{0};
|
|
389
|
+
};
|
|
390
|
+
|
|
368
391
|
extern "C" {
|
|
369
392
|
static void setCallback(lcb_INSTANCE *, lcb_CALLBACK_TYPE, const lcb_RESPSTORE *resp)
|
|
370
393
|
{
|
|
371
|
-
|
|
372
|
-
lcb_respstore_cookie(resp, (void **)&
|
|
394
|
+
upsert_result *res = nullptr;
|
|
395
|
+
lcb_respstore_cookie(resp, (void **)&res);
|
|
396
|
+
res->invoked = true;
|
|
373
397
|
lcb_STORE_OPERATION op;
|
|
374
398
|
lcb_respstore_operation(resp, &op);
|
|
375
399
|
ASSERT_EQ(LCB_STORE_UPSERT, op);
|
|
376
|
-
|
|
377
|
-
|
|
400
|
+
res->rc = lcb_respstore_status(resp);
|
|
401
|
+
lcb_respstore_cas(resp, &res->cas);
|
|
402
|
+
const char *ptr = nullptr;
|
|
403
|
+
std::size_t len = 0;
|
|
404
|
+
lcb_respstore_key(resp, &ptr, &len);
|
|
405
|
+
res->id.assign(ptr, len);
|
|
378
406
|
}
|
|
379
407
|
}
|
|
380
408
|
|
|
381
|
-
|
|
409
|
+
upsert_result upsert_doc(lcb_INSTANCE *instance, const string &scope, const string &collection)
|
|
382
410
|
{
|
|
383
411
|
(void)lcb_install_callback(instance, LCB_CALLBACK_STORE, (lcb_RESPCALLBACK)setCallback);
|
|
384
412
|
|
|
385
413
|
string key = unique_name("id");
|
|
386
|
-
string val =
|
|
414
|
+
string val = R"({"key":")" + key + "\"}";
|
|
387
415
|
|
|
388
|
-
int numcallbacks = 0;
|
|
389
416
|
lcb_CMDSTORE *cmd;
|
|
390
417
|
lcb_cmdstore_create(&cmd, LCB_STORE_UPSERT);
|
|
391
418
|
lcb_cmdstore_collection(cmd, scope.c_str(), scope.size(), collection.c_str(), collection.size());
|
|
392
419
|
lcb_cmdstore_key(cmd, key.c_str(), key.size());
|
|
393
420
|
lcb_cmdstore_value(cmd, val.c_str(), val.size());
|
|
394
|
-
|
|
395
|
-
|
|
421
|
+
upsert_result res{};
|
|
422
|
+
EXPECT_EQ(LCB_SUCCESS, lcb_store(instance, &res, cmd));
|
|
396
423
|
lcb_cmdstore_destroy(cmd);
|
|
397
|
-
|
|
424
|
+
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
425
|
+
EXPECT_TRUE(res.invoked);
|
|
426
|
+
EXPECT_STATUS_EQ(LCB_SUCCESS, res.rc);
|
|
427
|
+
return res;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
struct query_index {
|
|
431
|
+
std::string id{};
|
|
432
|
+
std::string name{};
|
|
433
|
+
bool is_primary{false};
|
|
434
|
+
std::string keyspace_id{};
|
|
435
|
+
std::string namespace_id{};
|
|
436
|
+
std::string bucket_id{};
|
|
437
|
+
std::string state{};
|
|
438
|
+
};
|
|
439
|
+
|
|
440
|
+
struct query_index_list {
|
|
441
|
+
bool invoked{false};
|
|
442
|
+
lcb_STATUS rc{LCB_ERR_GENERIC};
|
|
443
|
+
std::uint16_t http_code{0};
|
|
444
|
+
std::string meta{};
|
|
445
|
+
std::string status{};
|
|
446
|
+
vector<std::pair<unsigned int, string>> errors{};
|
|
447
|
+
std::vector<query_index> indexes{};
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
extern "C" {
|
|
451
|
+
static void list_indexes_callback(lcb_INSTANCE *, int, const lcb_RESPQUERY *resp)
|
|
452
|
+
{
|
|
453
|
+
query_index_list *res;
|
|
454
|
+
lcb_respquery_cookie(resp, (void **)&res);
|
|
455
|
+
|
|
456
|
+
const char *row;
|
|
457
|
+
size_t nrow;
|
|
458
|
+
lcb_respquery_row(resp, &row, &nrow);
|
|
459
|
+
|
|
460
|
+
if (lcb_respquery_is_final(resp)) {
|
|
461
|
+
res->rc = lcb_respquery_status(resp);
|
|
462
|
+
if (row) {
|
|
463
|
+
res->meta.assign(row, nrow);
|
|
464
|
+
Json::Value meta;
|
|
465
|
+
if (Json::Reader().parse(res->meta, meta)) {
|
|
466
|
+
if (meta.isMember("status") && meta["status"].isString()) {
|
|
467
|
+
res->status = meta["status"].asString();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (meta.isMember("errors") && meta["errors"].isArray()) {
|
|
471
|
+
for (auto &err : meta["errors"]) {
|
|
472
|
+
if (err.isObject()) {
|
|
473
|
+
res->errors.emplace_back(err["code"].asUInt(), err["msg"].asString());
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
const lcb_RESPHTTP *http = nullptr;
|
|
480
|
+
lcb_respquery_http_response(resp, &http);
|
|
481
|
+
if (http) {
|
|
482
|
+
lcb_resphttp_http_status(http, &res->http_code);
|
|
483
|
+
}
|
|
484
|
+
} else {
|
|
485
|
+
Json::Value index_json;
|
|
486
|
+
if (Json::Reader().parse(row, row + nrow, index_json)) {
|
|
487
|
+
query_index index{};
|
|
488
|
+
if (index_json.isMember("is_primary") && index_json["is_primary"].isBool()) {
|
|
489
|
+
index.is_primary = index_json["is_primary"].asBool();
|
|
490
|
+
}
|
|
491
|
+
if (index_json.isMember("id") && index_json["id"].isString()) {
|
|
492
|
+
index.id = index_json["id"].asString();
|
|
493
|
+
}
|
|
494
|
+
if (index_json.isMember("state") && index_json["state"].isString()) {
|
|
495
|
+
index.state = index_json["state"].asString();
|
|
496
|
+
}
|
|
497
|
+
if (index_json.isMember("name") && index_json["name"].isString()) {
|
|
498
|
+
index.name = index_json["name"].asString();
|
|
499
|
+
}
|
|
500
|
+
if (index_json.isMember("bucket_id") && index_json["bucket_id"].isString()) {
|
|
501
|
+
index.bucket_id = index_json["bucket_id"].asString();
|
|
502
|
+
}
|
|
503
|
+
if (index_json.isMember("keyspace_id") && index_json["keyspace_id"].isString()) {
|
|
504
|
+
index.keyspace_id = index_json["keyspace_id"].asString();
|
|
505
|
+
}
|
|
506
|
+
if (index_json.isMember("namespace_id") && index_json["namespace_id"].isString()) {
|
|
507
|
+
index.namespace_id = index_json["namespace_id"].asString();
|
|
508
|
+
}
|
|
509
|
+
res->indexes.emplace_back(index);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
res->invoked = true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
query_index_list list_indexes(lcb_INSTANCE *instance, const std::string &bucket_name = "default")
|
|
517
|
+
{
|
|
518
|
+
const std::string param = "bucket_name";
|
|
519
|
+
const std::string encoded_bucket_name = Json::FastWriter().write(Json::Value(bucket_name));
|
|
520
|
+
std::string statement = R"(
|
|
521
|
+
SELECT idx.* FROM system:indexes AS idx
|
|
522
|
+
WHERE
|
|
523
|
+
(
|
|
524
|
+
(keyspace_id = $bucket_name AND bucket_id IS MISSING)
|
|
525
|
+
OR
|
|
526
|
+
(bucket_id = $bucket_name)
|
|
527
|
+
)
|
|
528
|
+
AND `using`="gsi"
|
|
529
|
+
ORDER BY is_primary DESC, name ASC)";
|
|
530
|
+
lcb_CMDQUERY *cmd;
|
|
531
|
+
lcb_cmdquery_create(&cmd);
|
|
532
|
+
lcb_cmdquery_statement(cmd, statement.c_str(), statement.size());
|
|
533
|
+
lcb_cmdquery_callback(cmd, list_indexes_callback);
|
|
534
|
+
EXPECT_STATUS_EQ(LCB_SUCCESS, lcb_cmdquery_named_param(cmd, param.data(), param.size(), encoded_bucket_name.data(),
|
|
535
|
+
encoded_bucket_name.size()));
|
|
536
|
+
query_index_list indexes{};
|
|
537
|
+
lcb_STATUS rc = lcb_query(instance, &indexes, cmd);
|
|
538
|
+
lcb_cmdquery_destroy(cmd);
|
|
539
|
+
EXPECT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
540
|
+
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
541
|
+
return indexes;
|
|
398
542
|
}
|
|
399
543
|
|
|
400
|
-
|
|
544
|
+
struct index_status_result {
|
|
545
|
+
bool invoked{false};
|
|
546
|
+
lcb_STATUS rc{LCB_ERR_GENERIC};
|
|
547
|
+
std::uint16_t status{};
|
|
548
|
+
std::string body{};
|
|
549
|
+
};
|
|
550
|
+
|
|
551
|
+
extern "C" {
|
|
552
|
+
static void index_status_callback(lcb_INSTANCE *, lcb_CALLBACK_TYPE, const lcb_RESPHTTP *resp)
|
|
553
|
+
{
|
|
554
|
+
index_status_result *res = nullptr;
|
|
555
|
+
lcb_resphttp_cookie(resp, (void **)&res);
|
|
556
|
+
res->invoked = true;
|
|
557
|
+
res->rc = lcb_resphttp_status(resp);
|
|
558
|
+
const char *ptr = nullptr;
|
|
559
|
+
std::size_t len = 0;
|
|
560
|
+
lcb_resphttp_body(resp, &ptr, &len);
|
|
561
|
+
res->body.assign(ptr, len);
|
|
562
|
+
lcb_resphttp_http_status(resp, &res->status);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
struct index_stats_point {
|
|
567
|
+
std::uint32_t timestamp{0};
|
|
568
|
+
std::uint32_t index_items_count{0};
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
std::vector<index_stats_point> index_status(lcb_INSTANCE *instance, const std::string &scope,
|
|
572
|
+
const std::string &collection, const std::string &index)
|
|
573
|
+
{
|
|
574
|
+
const std::string path{"/pools/default/stats/range"};
|
|
575
|
+
auto old_callback = lcb_install_callback(instance, LCB_CALLBACK_HTTP, (lcb_RESPCALLBACK)index_status_callback);
|
|
576
|
+
|
|
577
|
+
std::string payload =
|
|
578
|
+
R"(
|
|
579
|
+
[
|
|
580
|
+
{
|
|
581
|
+
"step": 3,
|
|
582
|
+
"start": -3,
|
|
583
|
+
"metric": [
|
|
584
|
+
{"label": "name", "value": "index_items_count"},
|
|
585
|
+
{"label": "bucket", "value": "default"},
|
|
586
|
+
{"label": "scope", "value": ")" +
|
|
587
|
+
scope + R"("},
|
|
588
|
+
{"label": "collection", "value": ")" +
|
|
589
|
+
collection + R"("},
|
|
590
|
+
{"label": "index", "value": ")" +
|
|
591
|
+
index + R"("}
|
|
592
|
+
],
|
|
593
|
+
"nodesAggregation": "sum"
|
|
594
|
+
}
|
|
595
|
+
]
|
|
596
|
+
)";
|
|
597
|
+
|
|
598
|
+
lcb_CMDHTTP *cmd;
|
|
599
|
+
lcb_cmdhttp_create(&cmd, LCB_HTTP_TYPE_MANAGEMENT);
|
|
600
|
+
lcb_cmdhttp_method(cmd, LCB_HTTP_METHOD_POST);
|
|
601
|
+
lcb_cmdhttp_path(cmd, path.data(), path.size());
|
|
602
|
+
lcb_cmdhttp_body(cmd, payload.data(), payload.size());
|
|
603
|
+
|
|
604
|
+
index_status_result res{};
|
|
605
|
+
lcb_STATUS rc = lcb_http(instance, &res, cmd);
|
|
606
|
+
lcb_cmdhttp_destroy(cmd);
|
|
607
|
+
EXPECT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
608
|
+
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
609
|
+
|
|
610
|
+
EXPECT_TRUE(res.invoked);
|
|
611
|
+
EXPECT_STATUS_EQ(LCB_SUCCESS, res.rc) << "http=" << res.status;
|
|
612
|
+
|
|
613
|
+
std::vector<index_stats_point> stats{};
|
|
614
|
+
Json::Value stats_json;
|
|
615
|
+
if (Json::Reader().parse(res.body, stats_json)) {
|
|
616
|
+
if (stats_json.isArray() && !stats_json.empty()) {
|
|
617
|
+
const auto &entry_json = stats_json[0];
|
|
618
|
+
if (entry_json.isObject() && entry_json.isMember("data") && entry_json["data"].isArray() &&
|
|
619
|
+
!entry_json["data"].empty()) {
|
|
620
|
+
const auto &metric_json = entry_json["data"][0];
|
|
621
|
+
if (metric_json.isObject() && metric_json.isMember("values") && metric_json["values"].isArray()) {
|
|
622
|
+
for (const auto &value : metric_json["values"]) {
|
|
623
|
+
if (value.isArray() && value.size() == 2) {
|
|
624
|
+
index_stats_point point{};
|
|
625
|
+
point.timestamp = value[0].asUInt();
|
|
626
|
+
point.index_items_count = std::stoul(value[1].asString());
|
|
627
|
+
stats.emplace_back(point);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
std::sort(stats.begin(), stats.end(),
|
|
636
|
+
[](const index_stats_point &a, const index_stats_point &b) { return a.timestamp < b.timestamp; });
|
|
637
|
+
|
|
638
|
+
lcb_install_callback(instance, LCB_CALLBACK_HTTP, old_callback);
|
|
639
|
+
return stats;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Sergey(2021-08-11): For some reason scoped indexes are really slow on Jenkins, this function, checks number of
|
|
644
|
+
* indexed documents and return when it is greater or equals to requested. See CCBC-1443.
|
|
645
|
+
*/
|
|
646
|
+
void wait_for_num_items_in_index(lcb_INSTANCE *instance, const string &scope, const string &collection,
|
|
647
|
+
const string &index, std::uint32_t expected)
|
|
648
|
+
{
|
|
649
|
+
std::uint32_t current = 0;
|
|
650
|
+
while (current < expected) {
|
|
651
|
+
auto stats = index_status(instance, scope, collection, index);
|
|
652
|
+
if (!stats.empty()) {
|
|
653
|
+
current = stats[stats.size() - 1].index_items_count;
|
|
654
|
+
if (current >= expected) {
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
sleep(1);
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
void create_index(lcb_INSTANCE *instance, const string &index, const string &scope, const string &collection,
|
|
663
|
+
bool wait_for_index = true)
|
|
401
664
|
{
|
|
402
665
|
string keyspace = "`default`:`default`.`" + scope + "`.`" + collection + "`";
|
|
403
666
|
string statement = "CREATE PRIMARY INDEX ";
|
|
@@ -416,6 +679,17 @@ void create_index(lcb_INSTANCE *instance, const string &index, const string &sco
|
|
|
416
679
|
ASSERT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
417
680
|
ASSERT_TRUE(handle != nullptr);
|
|
418
681
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
682
|
+
|
|
683
|
+
while (wait_for_index) {
|
|
684
|
+
auto query_indexes = list_indexes(instance);
|
|
685
|
+
ASSERT_STATUS_EQ(LCB_SUCCESS, query_indexes.rc) << "meta = " << query_indexes.meta;
|
|
686
|
+
if (std::any_of(query_indexes.indexes.begin(), query_indexes.indexes.end(), [&index](const query_index &entry) {
|
|
687
|
+
return entry.name == index && entry.state == "online";
|
|
688
|
+
})) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
usleep(100000);
|
|
692
|
+
}
|
|
419
693
|
}
|
|
420
694
|
|
|
421
695
|
/**
|
|
@@ -440,28 +714,31 @@ TEST_F(QueryUnitTest, testCollectionQuery)
|
|
|
440
714
|
lcb_INSTANCE *instance;
|
|
441
715
|
createConnection(hw, &instance);
|
|
442
716
|
|
|
717
|
+
// to ensure timeout comes from the query engine, and not generate by SDK
|
|
718
|
+
lcb_cntl_string(instance, "query_grace_period", "3" /* seconds */);
|
|
719
|
+
|
|
443
720
|
string scope = unique_name("scope");
|
|
444
721
|
string collection = unique_name("collection");
|
|
445
|
-
string index = "
|
|
722
|
+
string index = unique_name("index");
|
|
446
723
|
|
|
447
724
|
// Create a scope and collection
|
|
448
725
|
create_scope(instance, scope);
|
|
449
726
|
create_collection(instance, scope, collection);
|
|
450
|
-
sleep(5);
|
|
451
727
|
|
|
452
728
|
// Create an index on the collection
|
|
453
729
|
create_index(instance, index, scope, collection);
|
|
454
|
-
sleep(10); /* Wait for index to be available. Should replace with poll.*/
|
|
455
730
|
|
|
456
731
|
// Insert a doc
|
|
457
|
-
|
|
732
|
+
auto upsert_res = upsert_doc(instance, scope, collection);
|
|
733
|
+
wait_for_num_items_in_index(instance, scope, collection, index, 1);
|
|
458
734
|
|
|
459
735
|
N1QLResult res;
|
|
460
736
|
lcb_CMDQUERY *cmd;
|
|
461
737
|
lcb_cmdquery_create(&cmd);
|
|
462
|
-
string query = "SELECT * FROM `" + collection + "`
|
|
738
|
+
string query = "SELECT * FROM `" + collection + "` WHERE meta().id=\"" + upsert_res.id + "\"";
|
|
463
739
|
lcb_cmdquery_statement(cmd, query.c_str(), query.size());
|
|
464
740
|
lcb_cmdquery_consistency(cmd, LCB_QUERY_CONSISTENCY_REQUEST);
|
|
741
|
+
lcb_cmdquery_metrics(cmd, true);
|
|
465
742
|
lcb_cmdquery_callback(cmd, rowcb);
|
|
466
743
|
lcb_cmdquery_scope_name(cmd, scope.c_str(), scope.size());
|
|
467
744
|
|
|
@@ -473,8 +750,8 @@ TEST_F(QueryUnitTest, testCollectionQuery)
|
|
|
473
750
|
ASSERT_TRUE(handle != nullptr);
|
|
474
751
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
475
752
|
ASSERT_TRUE(res.called);
|
|
476
|
-
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc);
|
|
477
|
-
ASSERT_EQ(1, res.rows.size());
|
|
753
|
+
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc) << "http=" << res.htcode << ", meta=" << res.meta;
|
|
754
|
+
ASSERT_EQ(1, res.rows.size()) << "http=" << res.htcode << ", meta=" << res.meta;
|
|
478
755
|
drop_scope(instance, scope);
|
|
479
756
|
}
|
|
480
757
|
|
|
@@ -490,30 +767,29 @@ TEST_F(QueryUnitTest, testQueryWithUnknownCollection)
|
|
|
490
767
|
string collection = unique_name("collection1");
|
|
491
768
|
string unknown_scope = unique_name("scope2");
|
|
492
769
|
string unknown_collection = unique_name("collection2");
|
|
493
|
-
|
|
494
|
-
string index = "test-index";
|
|
770
|
+
string index = unique_name("index");
|
|
495
771
|
|
|
496
772
|
// Create a scope and collection
|
|
497
773
|
create_scope(instance, scope);
|
|
498
774
|
create_collection(instance, scope, collection);
|
|
499
|
-
sleep(5);
|
|
500
775
|
|
|
501
776
|
// Create an index on the collection
|
|
502
777
|
create_index(instance, index, scope, collection);
|
|
503
|
-
sleep(10); /* Wait for index to be available. Should replace with poll.*/
|
|
504
778
|
|
|
505
779
|
// Insert a doc
|
|
506
|
-
|
|
780
|
+
auto upsert_res = upsert_doc(instance, scope, collection);
|
|
781
|
+
wait_for_num_items_in_index(instance, scope, collection, index, 1);
|
|
507
782
|
|
|
508
783
|
{
|
|
509
784
|
// Query with unknown scope
|
|
510
785
|
N1QLResult res;
|
|
511
786
|
lcb_CMDQUERY *cmd;
|
|
512
787
|
lcb_cmdquery_create(&cmd);
|
|
513
|
-
string query = "SELECT * FROM `" + collection + "` where meta().id=\"" + id + "\"";
|
|
788
|
+
string query = "SELECT * FROM `" + collection + "` where meta().id=\"" + upsert_res.id + "\"";
|
|
514
789
|
lcb_cmdquery_statement(cmd, query.c_str(), query.size());
|
|
515
790
|
lcb_cmdquery_callback(cmd, rowcb);
|
|
516
791
|
lcb_cmdquery_scope_name(cmd, unknown_scope.c_str(), unknown_scope.size());
|
|
792
|
+
lcb_cmdquery_consistency(cmd, LCB_QUERY_CONSISTENCY_REQUEST);
|
|
517
793
|
|
|
518
794
|
lcb_QUERY_HANDLE *handle = nullptr;
|
|
519
795
|
lcb_cmdquery_handle(cmd, &handle);
|
|
@@ -532,7 +808,7 @@ TEST_F(QueryUnitTest, testQueryWithUnknownCollection)
|
|
|
532
808
|
N1QLResult res;
|
|
533
809
|
lcb_CMDQUERY *cmd;
|
|
534
810
|
lcb_cmdquery_create(&cmd);
|
|
535
|
-
string query = "SELECT * FROM `" + unknown_collection + "` where meta().id=\"" + id + "\"";
|
|
811
|
+
string query = "SELECT * FROM `" + unknown_collection + "` where meta().id=\"" + upsert_res.id + "\"";
|
|
536
812
|
lcb_cmdquery_statement(cmd, query.c_str(), query.size());
|
|
537
813
|
lcb_cmdquery_callback(cmd, rowcb);
|
|
538
814
|
lcb_cmdquery_scope_name(cmd, scope.c_str(), scope.size());
|
|
@@ -559,31 +835,32 @@ TEST_F(QueryUnitTest, testCollectionPreparedQuery)
|
|
|
559
835
|
HandleWrap hw;
|
|
560
836
|
lcb_INSTANCE *instance;
|
|
561
837
|
createConnection(hw, &instance);
|
|
838
|
+
lcb_cntl_string(instance, "query_grace_period", "3" /* seconds */);
|
|
562
839
|
|
|
563
840
|
string scope = unique_name("scope");
|
|
564
841
|
string collection = unique_name("collection");
|
|
565
|
-
string index = "
|
|
842
|
+
string index = unique_name("index");
|
|
566
843
|
|
|
567
844
|
// Create a scope and collection
|
|
568
845
|
create_scope(instance, scope);
|
|
569
846
|
create_collection(instance, scope, collection);
|
|
570
|
-
sleep(5);
|
|
571
847
|
|
|
572
848
|
// Create an index on the collection
|
|
573
849
|
create_index(instance, index, scope, collection);
|
|
574
|
-
sleep(10); /* Wait for index to be available. Should replace with poll.*/
|
|
575
850
|
|
|
576
851
|
// Insert a doc
|
|
577
|
-
|
|
852
|
+
auto upsert_res = upsert_doc(instance, scope, collection);
|
|
853
|
+
wait_for_num_items_in_index(instance, scope, collection, index, 1);
|
|
578
854
|
|
|
579
855
|
N1QLResult res;
|
|
580
856
|
lcb_CMDQUERY *cmd;
|
|
581
857
|
lcb_cmdquery_create(&cmd);
|
|
582
|
-
string query = "SELECT * FROM `" + collection + "` where meta().id=\"" + id + "\"";
|
|
858
|
+
string query = "SELECT * FROM `" + collection + "` where meta().id=\"" + upsert_res.id + "\"";
|
|
583
859
|
lcb_cmdquery_statement(cmd, query.c_str(), query.size());
|
|
584
860
|
lcb_cmdquery_callback(cmd, rowcb);
|
|
585
861
|
lcb_cmdquery_scope_name(cmd, scope.c_str(), scope.size());
|
|
586
862
|
lcb_cmdquery_adhoc(cmd, false);
|
|
863
|
+
lcb_cmdquery_consistency(cmd, LCB_QUERY_CONSISTENCY_REQUEST);
|
|
587
864
|
|
|
588
865
|
lcb_QUERY_HANDLE *handle = nullptr;
|
|
589
866
|
lcb_cmdquery_handle(cmd, &handle);
|
|
@@ -593,8 +870,8 @@ TEST_F(QueryUnitTest, testCollectionPreparedQuery)
|
|
|
593
870
|
ASSERT_TRUE(handle != nullptr);
|
|
594
871
|
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
595
872
|
ASSERT_TRUE(res.called);
|
|
596
|
-
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc) <<
|
|
597
|
-
ASSERT_EQ(1, res.rows.size());
|
|
873
|
+
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc) << "http=" << res.htcode << ", meta=" << res.meta;
|
|
874
|
+
ASSERT_EQ(1, res.rows.size()) << "http=" << res.htcode << ", meta=" << res.meta;
|
|
598
875
|
|
|
599
876
|
drop_scope(instance, scope);
|
|
600
877
|
}
|
|
@@ -865,3 +1142,23 @@ TEST_F(QueryUnitTest, testRawQuery)
|
|
|
865
1142
|
ASSERT_EQ("\"foo\"", res.rows[3]);
|
|
866
1143
|
ASSERT_EQ("false", res.rows[4]);
|
|
867
1144
|
}
|
|
1145
|
+
|
|
1146
|
+
TEST_F(QueryUnitTest, testReadOnlyWithNoResults)
|
|
1147
|
+
{
|
|
1148
|
+
SKIP_IF_CLUSTER_VERSION_IS_LOWER_THAN(MockEnvironment::VERSION_65)
|
|
1149
|
+
lcb_INSTANCE *instance;
|
|
1150
|
+
HandleWrap hw;
|
|
1151
|
+
if (!createClusterQueryConnection(hw, &instance)) {
|
|
1152
|
+
SKIP_CLUSTER_QUERY_TEST();
|
|
1153
|
+
}
|
|
1154
|
+
N1QLResult res;
|
|
1155
|
+
std::string query = "SELECT * FROM " + MockEnvironment::getInstance()->getBucket() + " LIMIT 0";
|
|
1156
|
+
makeCommand(query.c_str());
|
|
1157
|
+
lcb_cmdquery_readonly(cmd, 1);
|
|
1158
|
+
lcb_cmdquery_timeout(cmd, LCB_MS2US(3000));
|
|
1159
|
+
lcb_STATUS rc = lcb_query(instance, &res, cmd);
|
|
1160
|
+
ASSERT_STATUS_EQ(LCB_SUCCESS, rc);
|
|
1161
|
+
lcb_wait(instance, LCB_WAIT_DEFAULT);
|
|
1162
|
+
ASSERT_STATUS_EQ(LCB_SUCCESS, res.rc);
|
|
1163
|
+
ASSERT_EQ(0, res.rows.size());
|
|
1164
|
+
}
|