{"id":1790,"date":"2014-12-16T18:21:16","date_gmt":"2014-12-16T18:21:15","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1790"},"modified":"2023-06-28T01:17:48","modified_gmt":"2023-06-28T08:17:48","slug":"so-how-do-i-use-libcouchbase","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/","title":{"rendered":"So, how do I use this libcouchbase?"},"content":{"rendered":"<p>Some of you may have noticed that we released <a href=\"https:\/\/www.couchbase.com\/download\/\">Couchbase 1.8 earlier\u00a0today<\/a>, and a new set of smart clients for various languages. For me\u00a0personally this is a milestone, because <a href=\"https:\/\/www.couchbase.com\/develop\/c\/current\/\">libcouchbase<\/a> is now a supported client for the C language.<\/p>\n<p>So why do I care about that? Well, libcouchbase started out of my needs\u00a0to easily test various components of the server. Since I did most of\u00a0my development on the components on the server implemented in C, it\u00a0made sense for me to use C for my testing.<\/p>\n<p>I\u2019ve received some questions on how libcouchbase work in a\u00a0multithreaded context, so I should probably start off by clarifying\u00a0that: libcouchbase doesn&#8217;t use <b>any<\/b> form of locking to protect\u00a0it&#8217;s internal data structures, but it doesn&#8217;t mean you can&#8217;t use\u00a0libcouchbase in a multithreaded program. All it means is that you as a\u00a0client user must either use locking to protect yourself from accessing\u00a0the libcouchbase instance from multiple threads at the same time, or\u00a0just let each thread operate on it&#8217;s own instance of libcouchbase. One easy way to solve this is to have a &#8220;pool&#8221; of libcouchbase instances each thread pop and push its instance to whenever they need to access a Couchbase server. Access to this pool should be protected with a lock (but I guess you figured that out ;-)<\/p>\n<p>In this blog post I&#8217;ll create a demo program you may use to upload\u00a0JSON documents into a Couchbase server. You&#8217;ll find the complete\u00a0source available at <a href=\"https:\/\/github.com\/trondn\/vacuum\">https:\/\/github.com\/trondn\/vacuum<\/a> if you would like to try the example.<\/p>\n<p>The idea of this program is that it will &#8220;monitor&#8221; a directory and\u00a0upload all files appearing there into a Couchbase cluster. I&#8217;m pretty\u00a0sure most of you start thinking: &#8220;how do we do that in a portable\u00a0way?&#8221;. That&#8217;s not an easy task to do, so I&#8217;m not even going to try to\u00a0do that. I&#8217;ll try to write it in a <u>semi-portable<\/u>\u00a0way so that it\u00a0shouldn&#8217;t be that hard to implement on other platforms. That means\u00a0that I&#8217;m using the following limitations:<\/p>\n<ul class=\"bullet\">\n<li>I&#8217;m using <span style=\"font-family: 'Courier New', Courier, monospace\">opendir<\/span> and <span style=\"font-family: 'Courier New', Courier, monospace\">readdir<\/span> to traverse the directory. This can\u00a0easily be reimplemented with <span style=\"font-family: 'Courier New', Courier, monospace\">FindFirst<\/span> and <span style=\"font-family: 'Courier New', Courier, monospace\">FindNext<\/span> on Microsoft Windows.<\/li>\n<li>Monitor of the directory means that I&#8217;m going to scan the directory,\u00a0then sleep a given number of seconds before running another scan. I\u00a0know some platforms supports subscribing of changes to the\u00a0filesystem, but I&#8217;m not going to spend time on that (at least not right now ;-)).<\/li>\n<li>To avoid file locking or accessing the file while others are writing\u00a0the file, the clients should write the file into the directory with\u00a0a leading &#8220;dot&#8221; in the filename, and then rename the file when they\u00a0are done. The program ignores all files starting with a dot.<\/li>\n<\/ul>\n<p>So let&#8217;s jump to the code. The first piece of code that might be\u00a0interesting to look at would be where we create the libcouchbase\u00a0instance in main():<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0 instance = libcouchbase_create(host, user, passwd, bucket, NULL);<br \/>\nif (instance == NULL) {<br \/>\nfprintf(stderr, &#8220;Failed to create couchbase instancen&#8221;);<br \/>\nexit(EXIT_FAILURE);<br \/>\n}<\/div>\n<\/div>\n<p>The above code snippet creates the libcouchbase instance. There is no\u00a0way you can use a static structure for this, because doing so will\u00a0make it incredible hard to maintain binary compatibility. I like to be\u00a0able to fix bugs within the library and release new versions you may\u00a0use without having to recompile your program, and by hiding the\u00a0internal datastructures from the clients makes it easier to ensure\u00a0that the client don&#8217;t depend on their size. The first parameter to\u00a0<span style=\"font-family: 'Courier New', Courier, monospace\">libcouchbase_create<\/span> is the name (and port) of the REST port for the\u00a0couchbase server (default: localhost:8091). The second and third\u00a0parameter is the credentials you&#8217;d like to use to connect to the REST\u00a0port to get the pool information (default is to not authenticate). The\u00a0forth parameter is the bucket you&#8217;d like to connect to, and if you\u00a0don&#8217;t specify a bucket you&#8217;ll end up in the &#8220;default bucket&#8221;. The\u00a0fifth argument is a special object you may want to use if you are\u00a0going to use &#8220;advanced&#8221; features in libcouchbase. Most users will\u00a0probably just use the defaults and pass NULL here.<\/p>\n<p>The next thing we need to do is to set up some callback handlers to be\u00a0able to figure out what happens. In the example we&#8217;re only going to\u00a0use one operation (to load data into the cache) so we&#8217;ll need to set\u00a0up a handler to catch the result of storage operations. Unfortunately\u00a0we may also encounter problems, so we need to set up an error\u00a0handler (we&#8217;ll get back to work in a bit).<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0 libcouchbase_set_storage_callback(instance, storage_callback);<br \/>\nlibcouchbase_set_error_callback(instance, error_callback);<\/div>\n<\/div>\n<p>Now that we&#8217;ve created and initialized the instance, we need to try to connect to the Couchbase cluster:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0 libcouchbase_error_t ret = libcouchbase_connect(instance);<br \/>\nif (ret != LIBCOUCHBASE_SUCCESS) {<br \/>\nfprintf(stderr, &#8220;Failed to connect: %sn&#8221;,<br \/>\nlibcouchbase_strerror(instance, ret));<br \/>\nexit(EXIT_FAILURE);<br \/>\n}<\/div>\n<\/div>\n<p>Due to the fact that libcouchbase is fully asynchronous, all that\u00a0happened above was that we initiated the connect. That means that we\u00a0need to <b>wait<\/b> for the server to be connected to the Couchbase\u00a0cluster and connect to the correct bucket. If our program should do\u00a0other stuff now would be the time to do so, but since we don&#8217;t have\u00a0any other initialization to do we can just wait for it to complete:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0 libcouchbase_wait(instance);<\/div>\n<\/div>\n<p>One of the &#8220;cool&#8221; features we&#8217;ve got in libcouchbase is that it\u00a0provides an internal statistics interface, so we may tell it to\u00a0collect timing information of the operations with the following\u00a0snippet:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\n<p>\u00a0 \u00a0if ((ret = libcouchbase_enable_timings(instance) != LIBCOUCHBASE_SUCCESS)) {<br \/>\nfprintf(stderr, &#8220;Failed to enable timings: %sn&#8221;,<br \/>\nlibcouchbase_strerror(instance, ret));<br \/>\n}<\/p>\n<p>Our program is now fully initialized, and we can enter the main loop\u00a0that looks like pretty much like:<\/p>\n<\/div>\n<\/div>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0while (forever)<br \/>\n{<br \/>\nprocess_files();<br \/>\nsleep(nsec);<br \/>\n}<\/div>\n<\/div>\n<p>So how does our <span style=\"font-family: 'Courier New', Courier, monospace\">process_files()<\/span> look like? I&#8217;m not going to make the\u00a0example too big by pasting all of it, but the first piece in there\u00a0looks like:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0if (de-&gt;d_name[0] == &#8216;.&#8217;) {<br \/>\nif (strcmp(de-&gt;d_name, &#8220;.dump_stats&#8221;) == 0) {<br \/>\nfprintf(stdout, &#8220;Dumping stats:n&#8221;);<br \/>\nlibcouchbase_get_timings(instance, stdout, timings_callback);<br \/>\nfprintf(stdout, &#8220;&#8212;-n&#8221;);<br \/>\nremove(de-&gt;d_name);&lt;<br \/>\n}<br \/>\ncontinue;<br \/>\n}<\/div>\n<\/div>\n<p>As you see from the above code snippet we&#8217;ll ignore all files that\u00a0starts with a &#8216;<span style=\"font-family: 'Courier New', Courier, monospace\">.<\/span>&#8216; except for the file named &#8220;<span style=\"font-family: 'Courier New', Courier, monospace\">.dump_stats<\/span>&#8220;. Whenever we\u00a0see that file we dump the internal stats timings by using the\u00a0<span style=\"font-family: 'Courier New', Courier, monospace\">timings_callback<\/span> (I&#8217;ll get back to that later).<\/p>\n<p>The next thing we do is to try to read the file into memory and decode\u00a0it&#8217;s JSON before we try to get the &#8220;<span style=\"font-family: 'Courier New', Courier, monospace\">_id<\/span>&#8221; field to use as a key. If all\u00a0of that succeeds, we try to store the data in Coucbase with:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0 \u00a0 int error = 0;<br \/>\nret = libcouchbase_store(instance, &amp;error, LIBCOUCHBASE_SET,<br \/>\nid-&gt;valuestring, strlen(id-&gt;valuestring),<br \/>\nptr, size, 0, 0, 0);<br \/>\nif (ret == LIBCOUCHBASE_SUCCESS) {<br \/>\nlibcouchbase_wait(instance);<br \/>\n} else {<br \/>\nerror = 1;<br \/>\n}<\/div>\n<\/div>\n<p>The &amp;error piece here is quite interesting. It is a &#8220;cookie&#8221; passed to\u00a0the callback, so that I may know if I encountered a problem or\u00a0not. You&#8217;ll see how I&#8217;m using it when I discuss the <span style=\"font-family: 'Courier New', Courier, monospace\">storage_callback<\/span>\u00a0below.<\/p>\n<p>This is basically all of the important logic in the example. I\u00a0promised that I would get back to the different callbacks, so let&#8217;s\u00a0start by looking at the error callback:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0static void error_callback(libcouchbase_t instance,<br \/>\nlibcouchbase_error_t error,<br \/>\nconst char *errinfo)<br \/>\n{<br \/>\n\/* Ignore timeouts&#8230; *\/<br \/>\nif (error != LIBCOUCHBASE_ETIMEDOUT) {<br \/>\nfprintf(stderr, &#8220;rFATAL ERROR: %sn&#8221;,<br \/>\nlibcouchbase_strerror(instance, error));<br \/>\nif (errinfo &amp;&amp; strlen(errinfo) != 0) {<br \/>\nfprintf(stderr, &#8220;t&#8221;%s&#8221;n&#8221;, errinfo);<br \/>\n}<br \/>\nexit(EXIT_FAILURE);<br \/>\n}<br \/>\n}<\/div>\n<\/div>\n<p>As you see from the above snippet libcouchbase will call the\u00a0<span style=\"font-family: 'Courier New', Courier, monospace\">error_callback<\/span> whenever a timeout occurs, but we just want to retry\u00a0the operation. If we encounter a real error we print out an error\u00a0message and terminate the program.<\/p>\n<p>The next callback we use is the <span style=\"font-family: 'Courier New', Courier, monospace\">storage_callback<\/span>. It is called when\u00a0the store operation completed, so it is the right place for us to\u00a0figure out if an error occured while storing the data. Our callback\u00a0looks like:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\u00a0 \u00a0static void storage_callback(libcouchbase_t instance,<br \/>\nconst void *cookie,<br \/>\nlibcouchbase_storage_t operation,<br \/>\nlibcouchbase_error_t err,<br \/>\nconst void *key, size_t nkey,<br \/>\nuint64_t cas)<br \/>\n{<br \/>\nint *error = (void*)cookie;<br \/>\nif (err == LIBCOUCHBASE_SUCCESS) {<br \/>\n*error = 0;<br \/>\n} else {<br \/>\n*error = 1;<br \/>\nfprintf(stderr, &#8220;Failed to store &#8220;&#8221;);<br \/>\nfwrite(key, 1, nkey, stderr);<br \/>\nfprintf(stderr, &#8220;&#8221;: %sn&#8221;,<br \/>\nlibcouchbase_strerror(instance, err));<br \/>\nfflush(stderr);<br \/>\n}<br \/>\n}<\/div>\n<\/div>\n<p>As you see we&#8217;re storing the result of the operation in the integer\u00a0passed as the cookie. The observant reader may see that we might as\u00a0well could unlink the file and remove the memory from within the\u00a0callback (if we provided that information as the cookie instead ;))<\/p>\n<p>The last callback to cover is the timings callback we&#8217;re using to dump\u00a0out the timing statistics.<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\n<p>\u00a0 \u00a0static void timings_callback(libcouchbase_t instance, const void *cookie,<br \/>\nlibcouchbase_timeunit_t timeunit,<br \/>\nuint32_t min, uint32_t max,<br \/>\nuint32_t total, uint32_t maxtotal)<br \/>\n{<br \/>\nchar buffer[1024];<br \/>\nint offset = sprintf(buffer, &#8220;[%3u &#8211; %3u]&#8221;, min, max);<br \/>\nswitch (timeunit) {<br \/>\ncase LIBCOUCHBASE_TIMEUNIT_NSEC:<br \/>\noffset += sprintf(buffer + offset, &#8220;ns&#8221;);<br \/>\nbreak;<br \/>\ncase LIBCOUCHBASE_TIMEUNIT_USEC:<br \/>\noffset += sprintf(buffer + offset, &#8220;us&#8221;);<br \/>\nbreak;<br \/>\ncase LIBCOUCHBASE_TIMEUNIT_MSEC:<br \/>\noffset += sprintf(buffer + offset, &#8220;ms&#8221;);<br \/>\nbreak;<br \/>\ncase LIBCOUCHBASE_TIMEUNIT_SEC:<br \/>\noffset += sprintf(buffer + offset, &#8220;s&#8221;);<br \/>\nbreak;<br \/>\ndefault:<br \/>\n;<br \/>\n}<\/p>\n<p>int num = (float)40.0 * (float)total \/ (float)maxtotal;<br \/>\noffset += sprintf(buffer + offset, &#8221; |&#8221;);<br \/>\nfor (int ii = 0; ii &lt; num; ++ii) {<br \/>\noffset += sprintf(buffer + offset, &#8220;#&#8221;);<br \/>\n}<\/p>\n<p>offset += sprintf(buffer + offset, &#8221; &#8211; %un&#8221;, total);<br \/>\nfputs(buffer, (FILE*)cookie);<br \/>\n}<\/p>\n<\/div>\n<\/div>\n<p>When you request the timings from libcouchbase it reports all of the\u00a0timing metrics collected by calling the timings callback. As you can\u00a0see from the API you&#8217;ll get the minimum, maximum value for the range,\u00a0and the number of operations performed within that range. These\u00a0metrics are not to be considered as exact numbers, because they depend\u00a0on when what you do in your client code from the time you call the\u00a0operation until you call libcouchbase_wait for the operation to\u00a0complete.<\/p>\n<p>So let&#8217;s run the go ahead and run the program. I&#8217;ve prepopulated\u00a0<span style=\"font-family: 'Courier New', Courier, monospace\">\/var\/spool\/vacuum<\/span> with a number of JSON files, to have the program do\u00a0something.<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">trond@illumos ~&gt; .\/vacuum<br \/>\nsleeping 3 secs before retry..<\/div>\n<\/div>\n<p>From another withdow I execute the command:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">trond@illumos ~&gt; touch \/var\/spool\/vacuum\/.dump_stats<\/div>\n<\/div>\n<p>And when the timer expires in first window, it prints out:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">Dumping stats:<br \/>\n[ 60 &#8211; \u00a069]us |######################################## &#8211; 18<br \/>\n[ 70 &#8211; \u00a079]us |## &#8211; 1<br \/>\n[240 &#8211; 249]us |## &#8211; 1<br \/>\n&#8212;-<br \/>\nsleeping 3 secs before retry..<\/div>\n<\/div>\n<p>Hopefully this blog revealed how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. We&#8217;ve got various clients for\u00a0other programming languages like PHP and Ruby built on top of\u00a0libcouchbase, so I can promise you that you&#8217;ll see more functionallity\u00a0added!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some of you may have noticed that we released Couchbase 1.8 earlier\u00a0today, and a new set of smart clients for various languages. For me\u00a0personally this is a milestone, because libcouchbase is now a supported client for the C language. So [&hellip;]<\/p>\n","protected":false},"author":14,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8981],"class_list":["post-1790","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>So, how do I use this libcouchbase? - The Couchbase Blog<\/title>\n<meta name=\"description\" content=\"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"So, how do I use this libcouchbase?\" \/>\n<meta property=\"og:description\" content=\"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T18:21:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-28T08:17:48+00:00\" \/>\n<meta name=\"author\" content=\"Trond Norbye, Senior Developer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Trond Norbye, Senior Developer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\"},\"author\":{\"name\":\"Trond Norbye, Senior Developer, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d\"},\"headline\":\"So, how do I use this libcouchbase?\",\"datePublished\":\"2014-12-16T18:21:15+00:00\",\"dateModified\":\"2023-06-28T08:17:48+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\"},\"wordCount\":1860,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\",\"name\":\"So, how do I use this libcouchbase? - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T18:21:15+00:00\",\"dateModified\":\"2023-06-28T08:17:48+00:00\",\"description\":\"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"So, how do I use this libcouchbase?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d\",\"name\":\"Trond Norbye, Senior Developer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/03d13b4ab5eaa14c91cab7658f04df07\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g\",\"caption\":\"Trond Norbye, Senior Developer, Couchbase\"},\"description\":\"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/trond-norbye\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"So, how do I use this libcouchbase? - The Couchbase Blog","description":"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/","og_locale":"en_US","og_type":"article","og_title":"So, how do I use this libcouchbase?","og_description":"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.","og_url":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T18:21:15+00:00","article_modified_time":"2023-06-28T08:17:48+00:00","author":"Trond Norbye, Senior Developer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Trond Norbye, Senior Developer, Couchbase","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/"},"author":{"name":"Trond Norbye, Senior Developer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d"},"headline":"So, how do I use this libcouchbase?","datePublished":"2014-12-16T18:21:15+00:00","dateModified":"2023-06-28T08:17:48+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/"},"wordCount":1860,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/","url":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/","name":"So, how do I use this libcouchbase? - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T18:21:15+00:00","dateModified":"2023-06-28T08:17:48+00:00","description":"Learn more about how easy it is to use libcouchbase to\u00a0communicate with a Couchbase cluster. Also read how libcouchbase work in a\u00a0multithreaded context.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/so-how-do-i-use-libcouchbase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"So, how do I use this libcouchbase?"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/ef0f9ff42d878c2fc0ab3a685e96f36d","name":"Trond Norbye, Senior Developer, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/03d13b4ab5eaa14c91cab7658f04df07","url":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","caption":"Trond Norbye, Senior Developer, Couchbase"},"description":"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries.","url":"https:\/\/www.couchbase.com\/blog\/author\/trond-norbye\/"}]}},"authors":[{"term_id":8981,"user_id":14,"is_guest":0,"slug":"trond-norbye","display_name":"Trond Norbye, Senior Developer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bf3c00ca228efa25f7bfc168f566d6389279b44d4bbba4683c260a8bf33da03d?s=96&d=mm&r=g","author_category":"","last_name":"Norbye","first_name":"Trond","job_title":"","user_url":"","description":"Trond Norbye is a Software Architect at Couchbase. Core contributor to Couchbase &amp; Memcached projects. Created the C\/C++ &amp; node.js Couchbase client libraries."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1790","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=1790"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/1790\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=1790"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=1790"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=1790"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=1790"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}