Enable keys() to list elements without fetching values from server
Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
parent
47a5f5238f
commit
8cbc70aafb
11
README.md
11
README.md
|
|
@ -557,6 +557,17 @@ keys defined by the prefix. mkdir method is removed since etcdv3 treats everythi
|
|||
}
|
||||
```
|
||||
|
||||
etcd-cpp-apiv3 supports lists keys only without fetching values from etcd server:
|
||||
|
||||
```c++
|
||||
etcd::Client etcd("http://127.0.0.1:2379");
|
||||
etcd::Response resp = etcd.keys("/test/new_dir").get();
|
||||
for (int i = 0; i < resp.keys().size(); ++i)
|
||||
{
|
||||
std::cout << resp.keys(i);
|
||||
}
|
||||
```
|
||||
|
||||
3. Removing directory:
|
||||
|
||||
If you want the delete recursively then you have to pass a second `true` parameter
|
||||
|
|
|
|||
|
|
@ -373,12 +373,6 @@ namespace etcd
|
|||
*/
|
||||
pplx::task<Response> rm_if(std::string const & key, int64_t old_index);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key.
|
||||
* @param key is the key to be listed
|
||||
*/
|
||||
pplx::task<Response> ls(std::string const & key);
|
||||
|
||||
/**
|
||||
* Removes a directory node. Fails if the parent directory dos not exists or not a directory.
|
||||
* @param key is the directory to be created to be listed
|
||||
|
|
@ -405,7 +399,15 @@ namespace etcd
|
|||
pplx::task<Response> rmdir(std::string const & key, std::string const &range_end);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key.
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
*/
|
||||
pplx::task<Response> ls(std::string const & key);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
|
|
@ -421,10 +423,9 @@ namespace etcd
|
|||
*/
|
||||
pplx::task<Response> ls(std::string const & key, std::string const &range_end);
|
||||
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key and range_end, i.e., get
|
||||
* all keys in the range [key, range_end).
|
||||
* all keys in the range [key, range_end), and respects the given limit.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
|
|
@ -433,6 +434,50 @@ namespace etcd
|
|||
*/
|
||||
pplx::task<Response> ls(std::string const & key, std::string const &range_end, size_t const limit);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
*/
|
||||
pplx::task<Response> keys(std::string const & key);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
*/
|
||||
pplx::task<Response> keys(std::string const & key, size_t const limit);
|
||||
|
||||
/**
|
||||
* List keys identified by the key and range_end, i.e., get all keys in the range [key,
|
||||
* range_end), and respects the given limit.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
*/
|
||||
pplx::task<Response> keys(std::string const & key, std::string const &range_end);
|
||||
|
||||
/**
|
||||
* List keys identified by the key and range_end, i.e., get all keys in the range [key,
|
||||
* range_end).
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
*/
|
||||
pplx::task<Response> keys(std::string const & key, std::string const &range_end, size_t const limit);
|
||||
|
||||
/**
|
||||
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
|
||||
* a new key is created, like "/testdir/newkey" then no change happened in the value of
|
||||
|
|
|
|||
|
|
@ -454,13 +454,15 @@ namespace etcd
|
|||
Response rmdir(std::string const & key, std::string const &range_end);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key.
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
*/
|
||||
Response ls(std::string const & key);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key.
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
|
|
@ -478,7 +480,7 @@ namespace etcd
|
|||
|
||||
/**
|
||||
* Gets a directory listing of the directory identified by the key and range_end, i.e., get
|
||||
* all keys in the range [key, range_end).
|
||||
* all keys in the range [key, range_end), and respects the given limit.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
|
|
@ -487,6 +489,50 @@ namespace etcd
|
|||
*/
|
||||
Response ls(std::string const & key, std::string const &range_end, size_t const limit);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
*/
|
||||
Response keys(std::string const & key);
|
||||
|
||||
/**
|
||||
* Gets a directory listing of the directory prefixed by the key.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
*/
|
||||
Response keys(std::string const & key, size_t const limit);
|
||||
|
||||
/**
|
||||
* List keys identified by the key and range_end, i.e., get all keys in the range [key,
|
||||
* range_end).
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
*/
|
||||
Response keys(std::string const & key, std::string const &range_end);
|
||||
|
||||
/**
|
||||
* List keys identified by the key and range_end, i.e., get all keys in the range [key,
|
||||
* range_end), and respects the given limit.
|
||||
*
|
||||
* Note that only keys are included in the response.
|
||||
*
|
||||
* @param key is the key to be listed
|
||||
* @param range_end is the end of key range to be listed
|
||||
* @param limit is the size limit of results to be listed, we don't use default parameters
|
||||
* to ensure backwards binary compatibility.
|
||||
*/
|
||||
Response keys(std::string const & key, std::string const &range_end, size_t const limit);
|
||||
|
||||
/**
|
||||
* Watches for changes of a key or a subtree. Please note that if you watch e.g. "/testdir" and
|
||||
* a new key is created, like "/testdir/newkey" then no change happened in the value of
|
||||
|
|
@ -684,8 +730,8 @@ namespace etcd
|
|||
std::shared_ptr<etcdv3::AsyncCompareAndDeleteAction> rm_if_internal(std::string const & key, int64_t old_index, const std::string & old_value, etcdv3::AtomicityType const & atomicity_type);
|
||||
std::shared_ptr<etcdv3::AsyncDeleteAction> rmdir_internal(std::string const & key, bool recursive = false);
|
||||
std::shared_ptr<etcdv3::AsyncDeleteAction> rmdir_internal(std::string const & key, std::string const &range_end);
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> ls_internal(std::string const & key, size_t const limit);
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> ls_internal(std::string const & key, std::string const &range_end, size_t const limit);
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> ls_internal(std::string const & key, size_t const limit, bool const keys_only = false);
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> ls_internal(std::string const & key, std::string const &range_end, size_t const limit, bool const keys_only = false);
|
||||
std::shared_ptr<etcdv3::AsyncWatchAction> watch_internal(std::string const & key, int64_t fromIndex, bool recursive = false);
|
||||
std::shared_ptr<etcdv3::AsyncWatchAction> watch_internal(std::string const & key, std::string const &range_end, int64_t fromIndex);
|
||||
std::shared_ptr<etcdv3::AsyncLeaseRevokeAction> leaserevoke_internal(int64_t lease_id);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ namespace etcdv3
|
|||
std::string name; // for campaign (in v3election)
|
||||
std::string key;
|
||||
std::string range_end;
|
||||
bool keys_only;
|
||||
bool count_only;
|
||||
std::string value;
|
||||
std::string old_value;
|
||||
std::string auth_token;
|
||||
|
|
|
|||
|
|
@ -487,6 +487,34 @@ pplx::task<etcd::Response> etcd::Client::ls(std::string const & key, std::string
|
|||
this->client->ls_internal(key, range_end, limit));
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::keys(std::string const & key)
|
||||
{
|
||||
return etcd::detail::asyncify(
|
||||
static_cast<responser_t<etcdv3::AsyncRangeAction>>(Response::create),
|
||||
this->client->ls_internal(key, 0, true));
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::keys(std::string const & key, size_t const limit)
|
||||
{
|
||||
return etcd::detail::asyncify(
|
||||
static_cast<responser_t<etcdv3::AsyncRangeAction>>(Response::create),
|
||||
this->client->ls_internal(key, limit, true));
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::keys(std::string const & key, std::string const &range_end)
|
||||
{
|
||||
return etcd::detail::asyncify(
|
||||
static_cast<responser_t<etcdv3::AsyncRangeAction>>(Response::create),
|
||||
this->client->ls_internal(key, range_end, 0, true));
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::keys(std::string const & key, std::string const &range_end, size_t const limit)
|
||||
{
|
||||
return etcd::detail::asyncify(
|
||||
static_cast<responser_t<etcdv3::AsyncRangeAction>>(Response::create),
|
||||
this->client->ls_internal(key, range_end, limit, true));
|
||||
}
|
||||
|
||||
pplx::task<etcd::Response> etcd::Client::watch(std::string const & key, bool recursive)
|
||||
{
|
||||
return etcd::detail::asyncify(
|
||||
|
|
|
|||
|
|
@ -787,17 +787,6 @@ etcd::Response etcd::SyncClient::ls(std::string const & key, size_t const limit)
|
|||
return Response::create(this->ls_internal(key, limit));
|
||||
}
|
||||
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> etcd::SyncClient::ls_internal(std::string const & key, size_t const limit) {
|
||||
etcdv3::ActionParameters params;
|
||||
params.key.assign(key);
|
||||
params.withPrefix = true;
|
||||
params.limit = limit;
|
||||
params.auth_token.assign(this->token_authenticator->renew_if_expired());
|
||||
params.grpc_timeout = this->grpc_timeout;
|
||||
params.kv_stub = stubs->kvServiceStub.get();
|
||||
return std::make_shared<etcdv3::AsyncRangeAction>(std::move(params));
|
||||
}
|
||||
|
||||
etcd::Response etcd::SyncClient::ls(std::string const & key, std::string const &range_end)
|
||||
{
|
||||
return Response::create(this->ls_internal(key, range_end, 0 /* default: no limit */));
|
||||
|
|
@ -808,10 +797,43 @@ etcd::Response etcd::SyncClient::ls(std::string const & key, std::string const &
|
|||
return Response::create(this->ls_internal(key, range_end, limit));
|
||||
}
|
||||
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> etcd::SyncClient::ls_internal(std::string const & key, std::string const &range_end, size_t const limit) {
|
||||
etcd::Response etcd::SyncClient::keys(std::string const & key)
|
||||
{
|
||||
return Response::create(this->ls_internal(key, 0 /* default: no limit */, true));
|
||||
}
|
||||
|
||||
etcd::Response etcd::SyncClient::keys(std::string const & key, size_t const limit)
|
||||
{
|
||||
return Response::create(this->ls_internal(key, limit, true));
|
||||
}
|
||||
|
||||
etcd::Response etcd::SyncClient::keys(std::string const & key, std::string const &range_end)
|
||||
{
|
||||
return Response::create(this->ls_internal(key, range_end, 0 /* default: no limit */, true));
|
||||
}
|
||||
|
||||
etcd::Response etcd::SyncClient::keys(std::string const & key, std::string const &range_end, size_t const limit)
|
||||
{
|
||||
return Response::create(this->ls_internal(key, range_end, limit, true));
|
||||
}
|
||||
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> etcd::SyncClient::ls_internal(std::string const & key, size_t const limit, bool const keys_only) {
|
||||
etcdv3::ActionParameters params;
|
||||
params.key.assign(key);
|
||||
params.keys_only = keys_only;
|
||||
params.withPrefix = true;
|
||||
params.limit = limit;
|
||||
params.auth_token.assign(this->token_authenticator->renew_if_expired());
|
||||
params.grpc_timeout = this->grpc_timeout;
|
||||
params.kv_stub = stubs->kvServiceStub.get();
|
||||
return std::make_shared<etcdv3::AsyncRangeAction>(std::move(params));
|
||||
}
|
||||
|
||||
std::shared_ptr<etcdv3::AsyncRangeAction> etcd::SyncClient::ls_internal(std::string const & key, std::string const &range_end, size_t const limit, bool const keys_only) {
|
||||
etcdv3::ActionParameters params;
|
||||
params.key.assign(key);
|
||||
params.range_end.assign(range_end);
|
||||
params.keys_only = keys_only;
|
||||
params.withPrefix = false;
|
||||
params.limit = limit;
|
||||
params.auth_token.assign(this->token_authenticator->renew_if_expired());
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ etcdv3::ActionParameters::ActionParameters()
|
|||
old_revision = 0;
|
||||
lease_id = 0;
|
||||
ttl = 0;
|
||||
keys_only = false;
|
||||
count_only = false;
|
||||
kv_stub = NULL;
|
||||
watch_stub = NULL;
|
||||
lease_stub = NULL;
|
||||
|
|
@ -56,6 +58,8 @@ void etcdv3::ActionParameters::dump(std::ostream &os) const {
|
|||
os << " name: " << name << std::endl;
|
||||
os << " key: " << key << std::endl;
|
||||
os << " range_end: " << range_end << std::endl;
|
||||
os << " keys_only: " << keys_only << std::endl;
|
||||
os << " count_only: " << count_only << std::endl;
|
||||
os << " value: " << value << std::endl;
|
||||
os << " old_value: " << old_value << std::endl;
|
||||
os << " auth_token: " << auth_token << std::endl;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ etcdv3::AsyncRangeAction::AsyncRangeAction(
|
|||
}
|
||||
get_request.set_sort_order(RangeRequest::SortOrder::RangeRequest_SortOrder_NONE);
|
||||
|
||||
// set keys_only and count_only
|
||||
get_request.set_keys_only(params.keys_only);
|
||||
get_request.set_count_only(params.count_only);
|
||||
|
||||
response_reader = parameters.kv_stub->AsyncRange(&context,get_request,&cq_);
|
||||
response_reader->Finish(&reply, &status, (void*)this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,12 @@ TEST_CASE("sync operations")
|
|||
etcd.set("/test/new_dir/key2", "value2");
|
||||
CHECK(2 == etcd.ls("/test/new_dir").keys().size());
|
||||
|
||||
// keys
|
||||
CHECK(0 == etcd.keys("/test/new_dir").keys().size());
|
||||
etcd.set("/test/new_dir/key1", "value1");
|
||||
etcd.set("/test/new_dir/key2", "value2");
|
||||
CHECK(2 == etcd.keys("/test/new_dir").keys().size());
|
||||
|
||||
// rmdir
|
||||
CHECK(etcd::ERROR_KEY_NOT_FOUND == etcd.rmdir("/test/new_dir").error_code()); // key not found
|
||||
CHECK(0 == etcd.rmdir("/test/new_dir", true).error_code());
|
||||
|
|
|
|||
|
|
@ -326,6 +326,36 @@ TEST_CASE("list by range")
|
|||
CHECK(etcd.rmdir("/test/new_dir", true).get().is_ok());
|
||||
}
|
||||
|
||||
TEST_CASE("list by range, w/o values")
|
||||
{
|
||||
etcd::Client etcd(etcd_url);
|
||||
CHECK(0 == etcd.ls("/test/new_dir").get().keys().size());
|
||||
|
||||
etcd.set("/test/new_dir/key0", "value0").wait();
|
||||
etcd.set("/test/new_dir/key1", "value1").wait();
|
||||
etcd.set("/test/new_dir/key2", "value2").wait();
|
||||
etcd.set("/test/new_dir/key3", "value3").wait();
|
||||
etcd.set("/test/new_dir/key4", "value4").wait();
|
||||
|
||||
etcd::Response resp1 = etcd.ls("/test/new_dir/key1", "/test/new_dir/key3").get();
|
||||
REQUIRE(resp1.is_ok());
|
||||
CHECK("get" == resp1.action());
|
||||
REQUIRE(2 == resp1.keys().size());
|
||||
REQUIRE(2 == resp1.values().size());
|
||||
REQUIRE(resp1.values()[0].as_string() == "value0");
|
||||
REQUIRE(resp1.values()[1].as_string() == "value1");
|
||||
|
||||
etcd::Response resp2 = etcd.keys("/test/new_dir/key1", "/test/new_dir/key3").get();
|
||||
REQUIRE(resp1.is_ok());
|
||||
CHECK("get" == resp2.action());
|
||||
REQUIRE(2 == resp2.keys().size());
|
||||
REQUIRE(2 == resp2.values().size());
|
||||
REQUIRE(resp2.values()[0].as_string() == "");
|
||||
REQUIRE(resp2.values()[1].as_string() == "");
|
||||
|
||||
CHECK(etcd.rmdir("/test/new_dir", true).get().is_ok());
|
||||
}
|
||||
|
||||
TEST_CASE("delete a directory")
|
||||
{
|
||||
etcd::Client etcd(etcd_url);
|
||||
|
|
|
|||
Loading…
Reference in New Issue