C Client Library

Couchbase Server for C Development

The C library provides fast access to documents in Couchbase Server 2.0. With JSON documents and Couchbase server 2.0 you have new ways to index and query data stored in the cluster through views. This client library, libcouchbase, also simplifies requests to Views through its handling of HTTP transport.

This Couchbase Client Library for C and C++ provides a complete interface to the functionality of Couchbase Server. For more on writing C programs with Couchbase Server Getting Started guide.

Step 0: Get a Server

Get & Install Couchbase Server. Come back here when you're done.

Step 1: Get a Client Library

Installing

Install either with the package commands for your operating system or by adding the Couchbase repository to your operating system's package manager.

RHEL/CentOS 5.5

shell> sudo wget -O/etc/yum.repos.d/couchbase.repo http://packages.couchbase.com/rpm/couchbase-centos55-i386.repo
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo http://packages.couchbase.com/rpm/couchbase-centos55-x86_64.repo

RHEL/CentOS 6.2

shell> sudo wget -O/etc/yum.repos.d/couchbase.repo http://packages.couchbase.com/rpm/couchbase-centos62-i686.repo
shell> sudo wget -O/etc/yum.repos.d/couchbase.repo http://packages.couchbase.com/rpm/couchbase-centos62-x86_64.repo

Then to install libcouchbase itself, run:

shell> sudo yum check-update
shell> sudo yum install -y  libcouchbase2 libcouchbase-devel

Ubuntu 12.04 Precise Pangolin (Debian unstable)

Also compatible with recent versions, which have libevent2.

shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list http://packages.couchbase.com/ubuntu/couchbase-ubuntu1204.list

Ubuntu 11.10 Oneiric Ocelot (Debian unstable)

Also compatible with recent versions, which have libevent2.

shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list http://packages.couchbase.com/ubuntu/couchbase-ubuntu1110.list

Ubuntu 10.04 Lucid Lynx (Debian stable or testing)

shell> sudo wget -O/etc/apt/sources.list.d/couchbase.list http://packages.couchbase.com/ubuntu/couchbase-ubuntu1004.list

Also make sure you have the GPG key installed:

shell> wget -O- http://packages.couchbase.com/ubuntu/couchbase.key | sudo apt-key add -

Then to install libcouchbase itself run:

shell> sudo apt-get update
shell> sudo apt-get install libcouchbase2 libcouchbase-dev

Mac OS X

This client library is available via a homebrew recipe.  After installing homebrew, to install libcouchbase:

shell> brew install https://github.com/couchbase/homebrew/raw/stable/Library/Formula/libcouchbase.rb

This formula will soon be integrated in the official set of homebrew recipes.

Note: if you have upgraded to Mountain Lion after having installed homebrew previously, The Hitchhiker's Guide to Riding A Mountain Lion is a good guide to resolving any problems.

Step 2: Try it out!

Concepts

The C client library, a.k.a. libcouchbase, is a callback oriented client which makes it very easy to write high performance programs. There are a few ways you can drive IO with the library. The simplest is to use the synchronous interface over the asynch internals of the library. More advanced programs will want to either call the libcouchbase_wait() function after generating some operations, or drive the event loop themselves.

Connecting to a Cluster

Connecting to a cluster is straightforward:

struct lcb_create_st create_options;
lcb_t instance;
lcb_error_t err;

memset(&create_options, 0, sizeof(create_options));
create_options.v.v0.host = "myserver:8091";
create_options.v.v0.user = "mybucket";
create_options.v.v0.passwd = "secret";
create_options.v.v0.bucket = "mybucket";

err = lcb_create(&instance, &create_options);
if (err != LCB_SUCCESS) {
    fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
            lcb_strerror(NULL, err));
    return 1;
}

/* Set up the handler to catch all errors! */
lcb_set_error_callback(instance, error_callback);

/*
 * Initiate the connect sequence in libcouchbase
 */

if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
    fprintf(stderr, "Failed to initiate connect: %s\n",
            lcb_strerror(NULL, err));
    return 1;
}

/* Run the event loop and wait until we've connected */
lcb_wait(instance);

Using Callbacks

Callbacks are simple functions to handle the result of operations. For example:

/* the callback invoked by the library when receiving a get response */
static void get_callback(lcb_t instance,
                         const void *cookie,
                         lcb_error_t error,
                         const lcb_get_resp_t *resp)
{
    if (error != LCB_SUCCESS) {
        fprintf(stderr, "Failed to retrieve \"");
        fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
        fprintf(stderr, "\": %s\n", lcb_strerror(instance, error));
    } else {
        fprintf(stderr, "Data for key: \"");
        fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
        fprintf(stderr, "\" is : ");
        fwrite(resp->v.v0.bytes, 1, resp->v.v0.nbytes, stderr);
    }
}

Callbacks can be set up for all of your operations called in libcouchbase. In the API, you'll note the use of a "cookie". This is opaque data from your application which is associated with the request. Underlying libcouchbase will not inspect the field, or send it to the server.

Putting the connect logic and the get callback all together into a complete program with the include headers would be:

#include <libcouchbase/couchbase.h>
#include <stdlib.h>
#include <stdio.h>

static void error_callback(lcb_t instance,
                           lcb_error_t err,
                           const char *errinfo)
{
    fprintf(stderr, "Error %s: %s", lcb_strerror(instance, err),
            errinfo ? errinfo : "");
    exit(EXIT_FAILURE);
}

static void get_callback(lcb_t instance,
                         const void *cookie,
                         lcb_error_t error,
                         const lcb_get_resp_t *resp)
{
    if (error != LCB_SUCCESS) {
        fprintf(stderr, "Failed to retrieve \"");
        fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
        fprintf(stderr, "\": %s\n", lcb_strerror(instance, error));
    } else {
        fprintf(stderr, "Data for key: \"");
        fwrite(resp->v.v0.key, 1, resp->v.v0.nkey, stderr);
        fprintf(stderr, "\" is : ");
        fwrite(resp->v.v0.bytes, 1, resp->v.v0.nbytes, stderr);
    }
}

int main(void)
{
    struct lcb_create_st create_options;
    lcb_t instance;
    lcb_error_t err;

    memset(&create_options, 0, sizeof(create_options));
    create_options.v.v0.host = "myserver:8091";
    create_options.v.v0.user = "mybucket";
    create_options.v.v0.passwd = "secret";
    create_options.v.v0.bucket = "mybucket";

    err = lcb_create(&instance, &create_options);
    if (err != LCB_SUCCESS) {
        fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
                lcb_strerror(NULL, err));
        return 1;
    }

    /* Set up the handler to catch all errors! */
    lcb_set_error_callback(instance, error_callback);

    /*
     * Initiate the connect sequence in libcouchbase
     */

    if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
        fprintf(stderr, "Failed to initiate connect: %s\n",
                lcb_strerror(NULL, err));
        return 1;
    }

    /* Run the event loop and wait until we've connected */
    lcb_wait(instance);

    /*
     * Set up a callback for our get requests
     */

    lcb_set_get_callback(instance, get_callback);

    lcb_get_cmd_t cmd;
    const lcb_get_cmd_t * const commands[1] = { &cmd };
    memset(&cmd, 0, sizeof(cmd));
    cmd.v.v0.key = "foo";
    cmd.v.v0.nkey = 3;

    err = lcb_get(instance, NULL, 1, commands);
    if (err != LCB_SUCCESS) {
        fprintf(stderr, "Failed to get: %s\n",
                lcb_strerror(NULL, err));
        return 1;
    }

    lcb_wait(instance);

    lcb_destroy(instance);
    exit(EXIT_SUCCESS);
}

The API

In addition to the library headers installed with the client library, in the associated documentation, you will find an API reference.