Using lcb_get after lcb_arithmetic to get the value of a counter


#1

For my company, I’m writing a wrapper to libcouchbase to integrate with our proprietary scripting language. In our wrapper, we will support a limited set of the operations provided in libcouchbase, specifically the basic get, store, remove, and increment operations.

We will also support listing all the keys in a Couchbase bucket using a “primary index” view in which the keys will be the document IDs and no values will be emitted. We expect our users will store binary data and to avoid deserializing Base64-encoded data which is most likely stale, the user will be given the keys and will use the get operation to get the values directly. I’ve read that this is the recommended practice, and it appears to work well in our testing so far.

While I’ve been testing with this technique, I’ve noticed that when I fetch an atomic counter created with lcb_arithmetic using lcb_get, the value that is returned is the ASCII representation of the counter, not its 8-byte value, which is what I expected.

Is there a way to distinguish counters from other values when using lcb_get without having to do something like use sscanf or isdigit on each value to detect if it’s a number?


#2

The flags field is commonly used to indicate the value type. Please note however that there is a semi-official standard for what the flag values indicate.

We recommend using the value of 0x2000000 for JSON. (You can only set flags, however, using the lcb_store and not lcb_arithmetic).

Since an ASCII number is valid JSON, you can simply do something like:

scmd.v.v0.flags = 0x2000000;
scmd.v.v0.operation = LCB_ADD; // Don't overwrite
// other fields
lcb_store(...);

If LCB_ADD fails, you may then use lcb_arithmetic.

Finally, with lcb_get(), in the callback you can do something like:

static void get_callback(....)
{
  if (resp->v.v0.flags == 0x2000000 && isdigit(*(char*)resp->v.v0.bytes) {
    val = strtoull(....);
  }
}