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:
parent
9f09066b47
commit
1e72df7ca3
25
README.md
25
README.md
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue