public static void main(String[] args) {
// Run an operation on the database
db.run((Transaction tr) -> {
tr.set(Tuple.from(“hello”).pack(), Tuple.from(“world”).pack());
return null;
});
// Get the value of ‘hello’ from the database
String hello = db.run((Transaction tr) -> {
byte[] result = tr.get(Tuple.from(“hello”).pack()).join();
return Tuple.fromBytes(result).getString(0);
});
System.out.println("Hello " + hello);
}
This prints “Hello World” correctly.
However,
fdbcli doesn’t find the key.
Ah. So, it appears that the code tuple packs the keys (and values). This a totally reasonable thing to do (as it massages the data so that they sort correctly), but it does change the byte representation, so you won’t be able to run get Hello from the CLI. As it turns out, the correct byte encoding for “Hello” is \x02Hello\x00, so I would expect that you would see:
fdb> get \x02Hello\x00
`\x02Hello\x00' is `\x02world\x00'
We have more details as to how exactly tuple encoding works in the design directory. For strings, though, it is just (1) encode as UTF-8, (2) add a \x02 byte at the beginning, (3) a \x00 byte at the end, and (4) convert any zero bytes in the interior to \x00\xff.
In general when I want to see what data I’ve inserted during tests I run
getrange \x00 \xff
to see every (non-system) key. Obviously this is only useful for very small databases but often helps in dev if you’re not sure how everything is serialized.
Technically, to read everything you’d want to also include the empty key, which is a legal key in FoundationDB. In fdbcli, you would do the following:
getrange "" \xff
It should be noted that in fdbcli, you must use double quotes rather than single quotes for this (i.e. " instead of '). Single quotes are not treated as a special character, so using them will actually exclude everything that falls lexicographically before the single quote. For that reason, some intentionally use \x00 as the starting key if they know the empty key is unset to avoid hitting that pitfall.