Skip to content

Commit

Permalink
Bulk operations for C and Python
Browse files Browse the repository at this point in the history
  • Loading branch information
mnunberg committed Oct 15, 2015
1 parent 017e493 commit 0f82c76
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 4 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ This example should show how to get items out of the cluster
### Bulk Storing
This example should show how to store items into a cluster using the Bulk API

[C] |
[Python] |
[C](c/bulk-store.cc) |
[Python](python/bulk-operations.py) |
[Java] |
.NET |
[Go](go/bulk-insert.go) |
Expand All @@ -48,8 +48,8 @@ This example should show how to store items into a cluster using the Bulk API
### Bulk Retrieving
This example should show how to get items out of the cluster using the Bulk API

[C] |
[Python] |
[C](c/bulk-get.cc) |
[Python](python/bulk-operations.py) |
[Java] |
.NET |
[Go](go/bulk-get.go) |
Expand Down
89 changes: 89 additions & 0 deletions c/bulk-get.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include <libcouchbase/couchbase.h>
#include <libcouchbase/api3.h>
#include <vector>
#include <string>

struct Result {
lcb_error_t rc;
std::string key;
std::string value;
lcb_CAS cas;

Result(const lcb_RESPBASE *rb) :
rc(rb->rc),
key(reinterpret_cast<const char*>(rb->key), rb->nkey),
cas(rb->cas) {
}
};

typedef std::vector<Result> ResultList;

static void op_callback(lcb_t, int cbtype, const lcb_RESPBASE *rb)
{
ResultList *results = reinterpret_cast<ResultList*>(rb->cookie);
Result res(rb);

if (cbtype == LCB_CALLBACK_GET && rb->rc == LCB_SUCCESS) {
const lcb_RESPGET *rg = reinterpret_cast<const lcb_RESPGET*>(rb);
res.value.assign(reinterpret_cast<const char*>(rg->value), rg->nvalue);
}
results->push_back(res);
}

int main(int argc, char **argv)
{
lcb_t instance;
lcb_create_st crst;
lcb_error_t rc;

memset(&crst, 0, sizeof crst);
crst.version = 3;
crst.v.v3.connstr = "couchbase://10.0.0.31/default";
rc = lcb_create(&instance, &crst);
rc = lcb_connect(instance);
lcb_wait(instance);
rc = lcb_get_bootstrap_status(instance);

lcb_install_callback3(instance, LCB_CALLBACK_GET, op_callback);

// Make a list of keys to store initially
std::vector<std::string> toGet;
toGet.push_back("foo");
toGet.push_back("bar");
toGet.push_back("baz");

ResultList results;

lcb_sched_enter(instance);
std::vector<std::string>::const_iterator its = toGet.begin();
for (; its != toGet.end(); its++) {
lcb_CMDGET gcmd = { 0 };
LCB_CMD_SET_KEY(&gcmd, its->c_str(), its->size());
rc = lcb_get3(instance, &results, &gcmd);
if (rc != LCB_SUCCESS) {
fprintf(stderr, "Couldn't schedule item %s: %s\n",
its->c_str(), lcb_strerror(NULL, rc));

// Unschedules all operations since the last scheduling context
// (created by lcb_sched_enter)
lcb_sched_fail(instance);
break;
}
}
lcb_sched_leave(instance);
lcb_wait(instance);

ResultList::iterator itr;
for (itr = results.begin(); itr != results.end(); ++itr) {
printf("%s: ", itr->key.c_str());
if (itr->rc != LCB_SUCCESS) {
printf("Failed (%s)\n", lcb_strerror(NULL, itr->rc));
} else {
printf("Value=%.*s. CAS=%llu\n",
(int)itr->value.size(),itr->value.c_str(), itr->cas);
}
}

lcb_destroy(instance);
return 0;
}
91 changes: 91 additions & 0 deletions c/bulk-store.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#include <libcouchbase/couchbase.h>
#include <libcouchbase/api3.h>
#include <vector>
#include <map>
#include <string>

struct Result {
lcb_error_t rc;
std::string key;
std::string value;
lcb_CAS cas;

Result(const lcb_RESPBASE *rb) :
rc(rb->rc),
key(reinterpret_cast<const char*>(rb->key), rb->nkey),
cas(rb->cas) {
}
};

typedef std::vector<Result> ResultList;

static void op_callback(lcb_t, int cbtype, const lcb_RESPBASE *rb)
{
ResultList *results = reinterpret_cast<ResultList*>(rb->cookie);
Result res(rb);

if (cbtype == LCB_CALLBACK_GET && rb->rc == LCB_SUCCESS) {
const lcb_RESPGET *rg = reinterpret_cast<const lcb_RESPGET*>(rb);
res.value.assign(reinterpret_cast<const char*>(rg->value), rg->nvalue);
}
results->push_back(res);
}

int main(int argc, char **argv)
{
lcb_t instance;
lcb_create_st crst;
lcb_error_t rc;

memset(&crst, 0, sizeof crst);
crst.version = 3;
crst.v.v3.connstr = "couchbase://10.0.0.31/default";
rc = lcb_create(&instance, &crst);
rc = lcb_connect(instance);
lcb_wait(instance);
rc = lcb_get_bootstrap_status(instance);

lcb_install_callback3(instance, LCB_CALLBACK_STORE, op_callback);

// Make a list of keys to store initially
std::map<std::string, std::string> toStore;
toStore["foo"] = "{\"value\":\"fooValue\"}";
toStore["bar"] = "{\"value\":\"barValue\"}";
toStore["baz"] = "{\"value\":\"bazValue\"}";

ResultList results;

lcb_sched_enter(instance);
std::map<std::string,std::string>::const_iterator its = toStore.begin();
for (; its != toStore.end(); its++) {
lcb_CMDSTORE scmd = { 0 };
LCB_CMD_SET_KEY(&scmd, its->first.c_str(), its->first.size());
LCB_CMD_SET_VALUE(&scmd, its->second.c_str(), its->second.size());
scmd.operation = LCB_SET;
rc = lcb_store3(instance, &results, &scmd);
if (rc != LCB_SUCCESS) {
fprintf(stderr, "Couldn't schedule item %s: %s\n",
its->first.c_str(), lcb_strerror(NULL, rc));

// Unschedules all operations since the last scheduling context
// (created by lcb_sched_enter)
lcb_sched_fail(instance);
break;
}
}
lcb_sched_leave(instance);
lcb_wait(instance);

ResultList::iterator itr;
for (itr = results.begin(); itr != results.end(); ++itr) {
printf("%s: ", itr->key.c_str());
if (itr->rc != LCB_SUCCESS) {
printf("Failed (%s)\n", lcb_strerror(NULL, itr->rc));
} else {
printf("Stored. CAS=%llu\n", itr->cas);
}
}

lcb_destroy(instance);
return 0;
}
21 changes: 21 additions & 0 deletions python/bulk-operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python
from __future__ import print_function

from couchbase.bucket import Bucket

cb = Bucket('couchbase://10.0.0.31/default')

# First insert the documents we care about
cb.upsert_multi({
'foo': {'foo': 'value'},
'bar': {'bar': 'value'},
'baz': {'baz': 'value'}
})

# Get them back again
rvs = cb.get_multi(['foo', 'bar', 'baz'])
for key, info in rvs.items():
print('Value for {0}: {1}'.format(key, info.value))

# See other error handling examples showing how to handle errors
# in multi operations

0 comments on commit 0f82c76

Please sign in to comment.