Add test cases and documentation to show that binary data as key/value works well.

Signed-off-by: Tao He <sighingnow@gmail.com>
This commit is contained in:
Tao He 2022-10-18 00:51:19 +08:00
parent 9f09066b47
commit 1e72df7ca3
2 changed files with 78 additions and 0 deletions

View File

@ -438,6 +438,16 @@ the `created_index()` and the `modified_index()` methods.
} }
``` ```
### Put a value
You can put a key-value pair to etcd with the the `put()` method of the client instance. The only
parameter is the key and value to be put
```c++
etcd::Client etcd("http://127.0.0.1:2379");
pplx::task<etcd::Response> response_task = etcd.put("foo", "bar");
```
### Modifying a value ### Modifying a value
Setting the value of a key can be done with the `set()` method of the client. You simply pass Setting the value of a key can be done with the `set()` method of the client. You simply pass
@ -570,6 +580,21 @@ prefix will be deleted. All deleted keys will be placed in `response.values()` a
However, if recursive parameter is false, functionality will be the same as just deleting a key. However, if recursive parameter is false, functionality will be the same as just deleting a key.
The key supplied will NOT be treated as a prefix and will be treated as a normal key name. The key supplied will NOT be treated as a prefix and will be treated as a normal key name.
### Using binary data as key and value
Etcd itself support using arbitrary binary data as the key and value, i.e., the key and value
can contain `\NUL` (`\0`) and not necessary NUL-terminated strings. `std::string` in C++ supports
embed `\0` as well, but please note that when constructing `std::string` from a C-style string
the string will be terminated by the first `\0` character. Rather, you need to use the constructor
with the `count` parameter explicitly. When unpack a `std::string` that contains `\0`, you need
`.data()`, and `.c_str()` won't work.
```c++
std::string key = "key-foo\0bar";
std::string value = "value-foo\0bar";
etcd.put(key, value).wait();
```
### Lock ### Lock
Etcd lock has been supported as follows: Etcd lock has been supported as follows:

View File

@ -46,6 +46,59 @@ TEST_CASE("read a value from etcd")
CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a directory CHECK("" == etcd.get("/test").get().value().as_string()); // key points to a directory
} }
TEST_CASE("using binary keys and values, raw char pointer doesn't work")
{
etcd::Client etcd(etcd_url);
etcd.rmdir("/test", true).wait();
{
etcd::Response resp = etcd.put("/test/key1\0xyz", "42\0foo").get();
REQUIRE(resp.is_ok());
}
{
// should not exist
etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get();
CHECK(!resp.is_ok());
CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code());
}
{
// should exist
etcd::Response resp = etcd.get(std::string("/test/key1", 10)).get();
REQUIRE(resp.is_ok());
CHECK(std::string("42") == resp.value().as_string());
CHECK(std::string("42\0foo", 6) != resp.value().as_string());
}
{
// should exist
etcd::Response resp = etcd.get("/test/key1\0xyz").get();
REQUIRE(resp.is_ok());
CHECK(std::string("42") == resp.value().as_string());
CHECK(std::string("42\0foo", 6) != resp.value().as_string());
}
}
TEST_CASE("using binary keys and values, std::string is ok for \\0")
{
etcd::Client etcd(etcd_url);
etcd.rmdir("/test", true).wait();
{
etcd::Response resp = etcd.put(std::string("/test/key1\0xyz", 14), std::string("42\0foo", 6)).get();
REQUIRE(resp.is_ok());
}
{
// should not exist
etcd::Response resp = etcd.get("/test/key1").get();
CHECK(!resp.is_ok());
CHECK(etcd::ERROR_KEY_NOT_FOUND == resp.error_code());
}
{
// should exist
etcd::Response resp = etcd.get(std::string("/test/key1\0xyz", 14)).get();
REQUIRE(resp.is_ok());
CHECK(std::string("42") != resp.value().as_string());
CHECK(std::string("42\0foo", 6) == resp.value().as_string());
}
}
TEST_CASE("simplified read") TEST_CASE("simplified read")
{ {
etcd::Client etcd(etcd_url); etcd::Client etcd(etcd_url);