1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2010-2017 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #ifndef LIBCOUCHBASE_COUCHBASE_H
19 #define LIBCOUCHBASE_COUCHBASE_H 1
20 
21 /**
22  * @file
23  * Main header file for Couchbase
24  */
25 
26 #define LCB_CONFIG_MCD_PORT 11210
27 #define LCB_CONFIG_MCD_SSL_PORT 11207
28 #define LCB_CONFIG_HTTP_PORT 8091
29 #define LCB_CONFIG_HTTP_SSL_PORT 18091
30 #define LCB_CONFIG_MCCOMPAT_PORT 11211
31 
32 struct lcb_st;
33 
34 /**
35  * @ingroup lcb-init
36  * Library handle representing a connection to a cluster and its data buckets. The contents
37  * of this structure are opaque.
38  * @see lcb_create
39  * @see lcb_destroy
40  */
41 typedef struct lcb_st *lcb_t;
42 struct lcb_http_request_st;
43 typedef struct lcb_http_request_st *lcb_http_request_t;
44 
45 #include <stddef.h>
46 #include <time.h>
47 #include <stdarg.h>
48 #include <stdio.h>
49 #include <libcouchbase/sysdefs.h>
50 #include <libcouchbase/assert.h>
51 #include <libcouchbase/visibility.h>
52 #include <libcouchbase/error.h>
53 #include <libcouchbase/iops.h>
54 #include <libcouchbase/http.h>
55 #include <libcouchbase/configuration.h>
56 #include <libcouchbase/kvbuf.h>
57 #include <libcouchbase/auth.h>
58 #include <libcouchbase/tracing.h>
59 #include <libcouchbase/_cxxwrap.h>
60 #include <libcouchbase/cntl.h>
61 
62 #ifdef __cplusplus
63 extern "C"{
64 #endif
65 
66 typedef lcb_U8 lcb_datatype_t;
67 typedef lcb_U32 lcb_USECS;
68 
69 
70 /******************************************************************************
71  ******************************************************************************
72  ******************************************************************************
73  ** INITIALIZATION                                                           **
74  ******************************************************************************
75  ******************************************************************************
76  ******************************************************************************/
77 
78 /**
79  * @ingroup lcb-public-api
80  * @defgroup lcb-init Initialization
81  *
82  * @details
83  *
84  * To communicate with a Couchbase cluster, a new library handle instance is
85  * created in the form of an lcb_t. To create such an object, the lcb_create()
86  * function is called, passing it a structure of type lcb_create_st. The structure
87  * acts as a container for a union of other structures which are extended
88  * as more features are added. This container is forwards and backwards
89  * compatible, meaning that if the structure is extended, you code and application
90  * will still function if using an older version of the structure. The current
91  * sub-field of the lcb_create_st structure is the `v3` field.
92  *
93  * Connecting to the cluster involes the client knowing the necessary
94  * information needed to actually locate its services and connect to it.
95  *
96  * A connection specification consists of:
97  *
98  * 1. One or more hosts which comprise the cluster
99  * 2. The name of the bucket to access and perform operations on
100  * 3. The credentials of the bucket
101  *
102  * All these options are specified within the form of a URI in the form of
103  *
104  * `couchbase://$HOSTS/$BUCKET?$OPTIONS`
105  *
106  * @note
107  * If any of the fields (hosts, bucket, options) contain the `/` character then
108  * it _must_ be url-encoded; thus a bucket named `foo/bar` would be specified
109  * as `couchbase:///foo%2Fbar`
110  *
111  * @par Hosts
112  *
113  * In the most typical use case, you would specify a list of several hostnames
114  * delimited by a comma (`,`); each host specified should be a member of the
115  * cluster. The library will use this list to initially connect to the cluster.
116  *
117  * Note that it is not necessary to specify _all_ the nodes of the cluster as in
118  * a normal situation the library will only initially connect to one of the nodes.
119  * Passing multiple nodes increases the chance of a connection succeeding even
120  * if some of the nodes are currently down. Once connected to the cluster, the
121  * client will update itself with the other nodes actually found within the
122  * cluster and discard the list passed to it
123  *
124  * You can specify multiple hosts like so:
125  *
126  * `couchbase://foo.com,bar.com,baz.com`
127  *
128  * Or a single host:
129  *
130  * `couchbase://localhost`
131  *
132  * #### Specifying Ports and Protocol Options
133  *
134  * The default `couchbase://` scheme will assume all hosts and/or ports
135  * specify the _memcached_ port. If no port is specified, it is assumed
136  * that the port is _11210). For more extended options there are additional
137  * schemes available:
138  *
139  * * `couchbases://` - Will assume all ports refer to the SSL-enabled memcached
140  *   ports. This setting implicitly enables SSL on the instance as well. If no
141  *   ports are provided for the hosts, the implicit port for each host will be
142  *   _11207_.
143  *
144  * * `http://` - Will assume all ports refer to the HTTP REST API ports used
145  *   by Couchbase 2.2 and lower. These are also used when connecting to a
146  *   memcached bucket. If no port is specified it will be assumed the port is
147  *   _8091_.
148  *
149  * ### Bucket
150  *
151  * A bucket may be specified by using the optional _path_ component of the URI
152  * For protected buckets a password will still need to be supplied out of band.
153  *
154  * * `couchbase://1.1.1.1,2.2.2.2,3.3.3.3/users` - Connect to the `users`
155  *   bucket.
156  *
157  * ### Options
158  *
159  * @warning The key-value options here are considered to be an uncommitted interface
160  * as their names may change.
161  *
162  * Options can be specified as the _query_ part of the connection string,
163  * for example:
164  *
165  * `couchbase://cbnode.net/beer?operation_timeout=10000000`.
166  *
167  * Options may either be appropriate _key_ parameters for lcb_cntl_string()
168  * or one of the following:
169  *
170  * * `boostrap_on` - specify bootstrap protocols. Values can be `http` to force
171  *   old-style bootstrap mode for legacy clusters, `cccp` to force bootstrap
172  *   over the memcached port (For clusters 2.5 and above), or `all` to try with
173  *   _cccp_ and revert to _http_
174  *
175  * * `truststorepath` - Specify the path (on the local filesystem) to the server's
176  *   SSL certificate truststore. Only applicable if SSL is being used (i.e. the
177  *   scheme is `couchbases`). The trust store is optional, and when missing,
178  *   the library will use `certpath` as location for verification, and expect
179  *   any extra certificates to be concatenated in there.
180  *
181  * * `certpath` - Specify the path (on the local filesystem) to the server's
182  *   SSL certificate. Only applicable if SSL is being used (i.e. the scheme is
183  *   `couchbases`)
184  *
185  * * `keypath` - Specify the path (on the local filesystem) to the client
186  *   SSL private key. Only applicable if SSL client certificate authentication
187  *   is being used (i.e. the scheme is `couchbases` and `certpath` contains
188  *   client certificate). Read more in the server documentation:
189  *   https://developer.couchbase.com/documentation/server/5.0/security/security-certs-auth.html
190  *
191  * ### Bucket Identification and Credentials
192  *
193  * The most common settings you will wish to modify are the bucket name
194  *  and the credentials field (`user` and `passwd`). If a
195  * `bucket` is not specified it will revert to the `default` bucket (i.e. the
196  * bucket which is created when Couchbase Server is installed).
197  *
198  * The `user` and `passwd` fields authenticate for the bucket. This is only
199  * needed if you have configured your bucket to employ SASL auth. You can tell
200  * if the bucket has been configured with SASL auth by
201  *
202  * 1. Logging into the Couchbase Administration Console
203  * 2. Going to the _Data Buckets_ tab
204  * 3. Locate the row for your bucket
205  * 4. Expand the row into the detailed view (by clicking on the arrow at the
206  *    left of the row)
207  * 5. Click on _Edit_
208  * 6. Inspect the _Access Control_ section in the pop-up
209  *
210  * The bucket name is specified as the _path_ portion of the URI.
211  *
212  * For security purposes, the _user_ and _passwd_ cannot be specified within
213  * the URI
214  *
215  *
216  * @note
217  * You may not change the bucket or credentials after initializing the handle.
218  *
219  * #### Bootstrap Options
220  *
221  * The default configuration process will attempt to bootstrap first from
222  * the new memcached configuration protocol (CCCP) and if that fails, use
223  * the "HTTP" protocol via the REST API.
224  *
225  * The CCCP configuration will by default attempt to connect to one of
226  * the nodes specified on the port 11201. While normally the memcached port
227  * is determined by the configuration itself, this is not possible when
228  * the configuration has not been attained. You may specify a list of
229  * alternate memcached servers by using the 'mchosts' field.
230  *
231  * If you wish to modify the default bootstrap protocol selection, you
232  * can use the `bootstrap_on` option to specify the desired bootstrap
233  * specification
234  * to use for configuration (note that the ordering of this array is
235  * ignored). Using this mechanism, you can disable CCCP or HTTP.
236  *
237  * To force only "new-style" bootstrap, you may use `bootstrap_on=cccp`.
238  * To force only "old-style" bootstrap, use `bootstrap_on=http`. To force the
239  * default behavior, use `bootstrap_on=all`
240  *
241  *
242  * @addtogroup lcb-init
243  * @{
244  */
245 
246 /** @brief Handle types @see lcb_create_st3::type */
247 typedef enum {
248     LCB_TYPE_BUCKET = 0x00, /**< Handle for data access (default) */
249     LCB_TYPE_CLUSTER = 0x01 /**< Handle for administrative access */
250 } lcb_type_t;
251 
252 /**
253  * @brief Type of the bucket
254  *
255  * @see https://developer.couchbase.com/documentation/server/current/architecture/core-data-access-buckets.html
256  */
257 typedef enum {
258     LCB_BTYPE_UNSPEC = 0x00,    /**< Unknown or unspecified */
259     LCB_BTYPE_COUCHBASE = 0x01, /**< Data persisted and replicated */
260     LCB_BTYPE_EPHEMERAL = 0x02, /**< Data not persisted, but replicated */
261     LCB_BTYPE_MEMCACHED = 0x03  /**< Data not persisted and not replicated */
262 } lcb_BTYPE;
263 
264 
265 #ifndef __LCB_DOXYGEN__
266 /* These are definitions for some of the older fields of the `lcb_create_st`
267  * structure. They are here for backwards compatibility and should not be
268  * used by new code */
269 typedef enum { LCB_CONFIG_TRANSPORT_LIST_END = 0, LCB_CONFIG_TRANSPORT_HTTP = 1, LCB_CONFIG_TRANSPORT_CCCP, LCB_CONFIG_TRANSPORT_MAX } lcb_config_transport_t;
270 #define LCB_CREATE_V0_FIELDS const char *host; const char *user; const char *passwd; const char *bucket; struct lcb_io_opt_st *io;
271 #define LCB_CREATE_V1_FIELDS LCB_CREATE_V0_FIELDS lcb_type_t type;
272 #define LCB_CREATE_V2_FIELDS LCB_CREATE_V1_FIELDS const char *mchosts; const lcb_config_transport_t* transports;
273 struct lcb_create_st0 { LCB_CREATE_V0_FIELDS };
274 struct lcb_create_st1 { LCB_CREATE_V1_FIELDS };
275 struct lcb_create_st2 { LCB_CREATE_V2_FIELDS };
276 #endif
277 
278 /**
279  * @brief Inner structure V3 for lcb_create().
280  */
281 struct lcb_create_st3 {
282     const char *connstr; /**< Connection string */
283 
284     /**
285      * Username to use for authentication. This should only be set when
286      * connecting to a server 5.0 or greater.
287      */
288     const char *username;
289 
290     /**
291      * Password for bucket. Can also be password for username on servers >= 5.0
292      */
293     const char *passwd;
294 
295     void *_pad_bucket; /**< @private */
296     struct lcb_io_opt_st *io; /**< IO Options */
297     lcb_type_t type;
298 };
299 
300 /**
301  * @brief Inner structure V4 for lcb_create().
302  *
303  * Same as V3, but allows to supply logger (@see LCB_CNTL_LOGGER).
304  */
305 struct lcb_create_st4 {
306     const char *connstr; /**< Connection string */
307 
308     /**
309      * Username to use for authentication. This should only be set when
310      * connecting to a server 5.0 or greater.
311      */
312     const char *username;
313 
314     /**
315      * Password for bucket. Can also be password for username on servers >= 5.0
316      */
317     const char *passwd;
318 
319     lcb_logprocs *logger; /**< Logger */
320     struct lcb_io_opt_st *io; /**< IO Options */
321     lcb_type_t type;
322 };
323 
324 /**
325  * @brief Wrapper structure for lcb_create()
326  * @see lcb_create_st3
327  */
328 struct lcb_create_st {
329     /** Indicates which field in the @ref lcb_CRST_u union should be used. Set this to `3` */
330     int version;
331 
332     /**This union contains the set of current and historical options. The
333      * The #v3 field should be used. */
334     union lcb_CRST_u {
335         struct lcb_create_st0 v0;
336         struct lcb_create_st1 v1;
337         struct lcb_create_st2 v2;
338         struct lcb_create_st3 v3; /**< Use this field */
339         struct lcb_create_st4 v4;
340     } v;
341     LCB_DEPR_CTORS_CRST
342 };
343 
344 /**
345  * @brief Create an instance of lcb.
346  * @param instance Where the instance should be returned
347  * @param options How to create the libcouchbase instance
348  * @return LCB_SUCCESS on success
349  *
350  *
351  * ### Examples
352  * Create an instance using the default values:
353  *
354  * @code{.c}
355  * lcb_t instance;
356  * lcb_error_t err = lcb_create(&instance, NULL);
357  * if (err != LCB_SUCCESS) {
358  *    fprintf(stderr, "Failed to create instance: %s\n", lcb_strerror(NULL, err));
359  *    exit(EXIT_FAILURE);
360  * }
361  * @endcode
362  *
363  * Specify server list
364  *
365  * @code{.c}
366  * struct lcb_create_st options;
367  * memset(&options, 0, sizeof(options));
368  * options.version = 3;
369  * options.v.v3.connstr = "couchbase://host1,host2,host3";
370  * err = lcb_create(&instance, &options);
371  * @endcode
372  *
373  *
374  * Create a handle for data requests to protected bucket
375  *
376  * @code{.c}
377  * struct lcb_create_st options;
378  * memset(&options, 0, sizeof(options));
379  * options.version = 3;
380  * options.v.v3.host = "couchbase://example.com,example.org/protected"
381  * options.v.v3.passwd = "secret";
382  * err = lcb_create(&instance, &options);
383  * @endcode
384  * @committed
385  * @see lcb_create_st3
386  */
387 LIBCOUCHBASE_API
388 lcb_error_t lcb_create(lcb_t *instance, const struct lcb_create_st *options);
389 
390 /**
391  * @brief Schedule the initial connection
392  * This function will schedule the initial connection for the handle. This
393  * function _must_ be called before any operations can be performed.
394  *
395  * lcb_set_bootstrap_callback() or lcb_get_bootstrap_status() can be used to
396  * determine if the scheduled connection completed successfully.
397  *
398  * @par Synchronous Usage
399  * @code{.c}
400  * lcb_error_t rc = lcb_connect(instance);
401  * if (rc != LCB_SUCCESS) {
402  *    your_error_handling(rc);
403  * }
404  * lcb_wait(instance);
405  * rc = lcb_get_bootstrap_status(instance);
406  * if (rc != LCB_SUCCESS) {
407  *    your_error_handler(rc);
408  * }
409  * @endcode
410  * @committed
411  */
412 LIBCOUCHBASE_API
413 lcb_error_t lcb_connect(lcb_t instance);
414 
415 /**
416  * Bootstrap callback. Invoked once the instance is ready to perform operations
417  * @param instance The instance which was bootstrapped
418  * @param err The error code received. If this is not LCB_SUCCESS then the
419  * instance is not bootstrapped and must be recreated
420  *
421  * @attention This callback only receives information during instantiation.
422  * @committed
423  */
424 typedef void (*lcb_bootstrap_callback)(lcb_t instance, lcb_error_t err);
425 
426 /**
427  * @brief Set the callback for notification of success or failure of
428  * initial connection.
429  *
430  * @param instance the instance
431  * @param callback the callback to set. If `NULL`, return the existing callback
432  * @return The existing (and previous) callback.
433  * @see lcb_connect()
434  * @see lcb_get_bootstrap_status()
435  */
436 LIBCOUCHBASE_API
437 lcb_bootstrap_callback
438 lcb_set_bootstrap_callback(lcb_t instance, lcb_bootstrap_callback callback);
439 
440 /**
441  * @brief Gets the initial bootstrap status
442  *
443  * This is an alternative to using the lcb_bootstrap_callback() and may be used
444  * after the initial lcb_connect() and lcb_wait() sequence.
445  * @param instance
446  * @return LCB_SUCCESS if properly bootstrapped or an error code otherwise.
447  *
448  * @attention
449  * Calling this function only makes sense during instantiation.
450  * @committed
451  */
452 LIBCOUCHBASE_API
453 lcb_error_t
454 lcb_get_bootstrap_status(lcb_t instance);
455 
456 /**
457  * Sets the authenticator object for the instance. This may be done anytime, but
458  * should probably be done before calling `lcb_connect()` for best effect.
459  *
460  * @param instance the handle
461  * @param auth the authenticator object used. The library will increase the
462  * refcount on the authenticator object.
463  */
464 LIBCOUCHBASE_API
465 void
466 lcb_set_auth(lcb_t instance, lcb_AUTHENTICATOR *auth);
467 /**@}*/
468 
469 
470 
471 /**
472  * @ingroup lcb-public-api
473  * @defgroup lcb-kv-api Key/Value
474  *
475  * @brief Preview APIs for performing commands
476  *
477  * @details
478  * Basic command and structure definitions for public API. This represents the
479  * "V3" API of libcouchbase. This API replaces the legacy API (which now wraps
480  * this one). It contains common definitions for scheduling, response structures
481  * and callback signatures.
482  *
483  * @addtogroup lcb-kv-api
484  * @{
485  */
486 
487 /**
488  * @name Creating Commands
489  * @details
490  *
491  * Issuing a command to the Cluster involves selecting the correct command
492  * structure, populating it with the data relevant for the command, optionally
493  * associating the command with your own application data, issuing the command
494  * to a spooling function, and finally receiving the response.
495  *
496  * Command structures all derive from the common @ref lcb_CMDBASE structure. This
497  * structure defines the common fields for all commands.
498  *
499  * Almost all commands need to contain a key, which should be assigned using
500  * the LCB_CMD_SET_KEY() macro.
501  *
502  * @{*/
503 
504 #define LCB_CMD_BASE \
505     /**Common flags for the command. These modify the command itself. Currently
506      the lower 16 bits of this field are reserved, and the higher 16 bits are
507      used for individual commands.*/ \
508     lcb_U32 cmdflags; \
509     \
510     /**Specify the expiration time. This is either an absolute Unix time stamp
511      or a relative offset from now, in seconds. If the value of this number
512      is greater than the value of thirty days in seconds, then it is a Unix
513      timestamp.
514 
515      This field is used in mutation operations (lcb_store3()) to indicate
516      the lifetime of the item. It is used in lcb_get3() with the lcb_CMDGET::lock
517      option to indicate the lock expiration itself. */ \
518     lcb_U32 exptime; \
519     \
520     /**The known CAS of the item. This is passed to mutation to commands to
521      ensure the item is only changed if the server-side CAS value matches the
522      one specified here. For other operations (such as lcb_CMDENDURE) this
523      is used to ensure that the item has been persisted/replicated to a number
524      of servers with the value specified here. */ \
525     lcb_U64 cas; \
526     \
527     /**The key for the document itself. This should be set via LCB_CMD_SET_KEY() */ \
528     lcb_KEYBUF key; \
529     \
530     /** \volatile */ \
531     lcb_KEYBUF _hashkey
532 
533 /**@brief Common ABI header for all commands. _Any_ command may be safely
534  * casted to this type.*/
535 typedef struct lcb_CMDBASE {
536     LCB_CMD_BASE;
537 } lcb_CMDBASE;
538 
539 /**
540  * Flag for lcb_CMDBASE::cmdflags which indicates that the lcb_CMDBASE::cookie
541  * is a special callback object. This flag is used internally within the
542  * library.
543  *
544  * @internal
545  */
546 #define LCB_CMD_F_INTERNAL_CALLBACK (1 << 0)
547 
548 /**
549  * If this flag is set, then multiple authentication credentials will be passed
550  * to the server. By default only the bucket's credentials (i.e. bucket SASL
551  * password) are passed.
552  */
553 #define LCB_CMD_F_MULTIAUTH (1<<1)
554 
555 /**
556  * Set the key for the command.
557  * @param cmd A command derived from lcb_CMDBASE
558  * @param keybuf the buffer for the key
559  * @param keylen the length of the key.
560  *
561  * @code{.c}
562  * lcb_CMDGET cmd = { 0 };
563  * LCB_CMD_SET_KEY(&cmd, "key", strlen("key"));
564  * @endcode
565  *
566  * The storage for `keybuf` may be released or modified after the command has
567  * been spooled.
568  */
569 #define LCB_CMD_SET_KEY(cmd, keybuf, keylen) \
570         LCB_KREQ_SIMPLE(&(cmd)->key, keybuf, keylen)
571 
572 /**
573  * Sets the vBucket ID for the item. This accomplishes the same effect as
574  * _hashkey_ except that this assumes the vBucket has already been obtained.
575  *
576  * The intent of this API is to override the default vBucket hashing/calculation.
577  *
578  * @param cmd the command structure
579  * @param vbid the vBucket ID for the key.
580  * @volatile
581  */
582 #define LCB_CMD__SETVBID(cmd, vbid) do { \
583         (cmd)->_hashkey.type = LCB_KV_VBID; \
584         (cmd)->_hashkey.contig.nbytes = vbid; \
585 } while (0);
586 /**@}*/
587 
588 /**
589  * @name Receiving Responses
590  * @details
591  *
592  * This section describes the APIs used in receiving responses.
593  *
594  * Each command will have a callback invoked (typically once, for some commands
595  * this may be more than once) with a response structure. The response structure
596  * will be of a type that extends lcb_RESPBASE. The response structure should
597  * not be modified and any of its fields should be considered to point to memory
598  * which will be released after the callback exits.
599  *
600  * The common response header contains the lcb_RESPBASE::cookie field which
601  * is the pointer to your application context (passed as the second argument
602  * to the spooling function) and allows you to associate a specific command
603  * with a specific response.
604  *
605  * The header will also contain the key (lcb_RESPBASE::key) field which can
606  * also help identify the specific command. This is useful if you maintain a
607  * single _cookie_ for multiple commands, and have per-item specific data
608  * you wish to associate within the _cookie_ itself.
609  *
610  * Success or failure of the operation is signalled through the lcb_RESPBASE::rc
611  * field. Note that even in the case of failure, the lcb_RESPBASE::cookie and
612  * lcb_RESPBASE::key fields will _always_ be populated.
613  *
614  * Most commands also return the CAS of the item (as it exists on the server)
615  * and this is placed inside the lcb_RESPBASE::cas field, however it is
616  * only valid in the case where lcb_RESPBASE::rc is LCB_SUCCESS.
617  *
618  * @{
619  */
620 
621 #define LCB_RESP_BASE \
622     /**
623      Application-defined pointer passed as the `cookie` parameter when
624      scheduling the command.
625      */ \
626     void *cookie; \
627     const void *key; /**< Key for request */ \
628     lcb_SIZE nkey; /**< Size of key */ \
629     lcb_CAS cas; /**< CAS for response (if applicable) */ \
630     lcb_error_t rc; /**< Status code */ \
631     lcb_U16 version; /**< ABI version for response */ \
632     /** Response specific flags. see ::lcb_RESPFLAGS */ \
633     lcb_U16 rflags;
634 
635 
636 /**
637  * @brief
638  * Base response structure for callbacks.
639  * All responses structures derive from this ABI.
640  */
641 typedef struct {
642     LCB_RESP_BASE
643 } lcb_RESPBASE;
644 
645 
646 #define LCB_RESP_SERVER_FIELDS \
647     /** String containing the `host:port` of the server which sent this response */ \
648     const char *server;
649 
650 /**
651  * @brief Base structure for informational commands from servers
652  * This contains an additional lcb_RESPSERVERBASE::server field containing the
653  * server which emitted this response.
654  */
655 typedef struct {
656     LCB_RESP_BASE
657     LCB_RESP_SERVER_FIELDS
658 } lcb_RESPSERVERBASE;
659 
660 /** @ingroup lcb-mutation-tokens */
661 typedef struct lcb_MUTATION_TOKEN {
662     lcb_U64 uuid_; /**< Use LCB_MUTATION_TOKEN_ID() */
663     lcb_U64 seqno_; /**< Use LCB_MUTATION_TOKEN_SEQ() */
664     lcb_U16 vbid_; /**< Use LCB_MUTATION_TOKEN_VB() */
665 } lcb_MUTATION_TOKEN;
666 
667 /**
668  * @brief Response flags.
669  * These provide additional 'meta' information about the response
670  * One of more of these values can be set in @ref lcb_RESPBASE::rflags
671  */
672 typedef enum {
673     /** No more responses are to be received for this request */
674     LCB_RESP_F_FINAL = 0x01,
675 
676     /**The response was artificially generated inside the client.
677      * This does not contain reply data from the server for the command, but
678      * rather contains the basic fields to indicate success or failure and is
679      * otherwise empty.
680      */
681     LCB_RESP_F_CLIENTGEN = 0x02,
682 
683     /**The response was a result of a not-my-vbucket error */
684     LCB_RESP_F_NMVGEN = 0x04,
685 
686     /**The response has additional internal data.
687      * Used by lcb_resp_get_mutation_token() */
688     LCB_RESP_F_EXTDATA = 0x08,
689 
690     /**Flag, only valid for subdoc responses, indicates that the response was
691      * processed using the single-operation protocol. */
692     LCB_RESP_F_SDSINGLE = 0x10,
693 
694     /**The response has extra error information as value (see SDK-RFC-28). */
695     LCB_RESP_F_ERRINFO = 0x20
696 } lcb_RESPFLAGS;
697 
698 /**
699  * The type of response passed to the callback. This is used to install callbacks
700  * for the library and to distinguish between responses if a single callback
701  * is used for multiple response types.
702  *
703  * @note These callbacks may conflict with the older version 2 callbacks. The
704  * rules are as follows:
705  * * If a callback has been installed using lcb_install_callback3(), then
706  * the older version 2 callback will not be invoked for that operation. The order
707  * of installation does not matter.
708  * * If the LCB_CALLBACK_DEFAULT callback is installed, _none_ of the version 2
709  * callbacks are invoked.
710  */
711 typedef enum {
712     LCB_CALLBACK_DEFAULT = 0, /**< Default callback invoked as a fallback */
713     LCB_CALLBACK_GET, /**< lcb_get3() */
714     LCB_CALLBACK_STORE, /**< lcb_store3() */
715     LCB_CALLBACK_COUNTER, /**< lcb_counter3() */
716     LCB_CALLBACK_TOUCH, /**< lcb_touch3() */
717     LCB_CALLBACK_REMOVE, /**< lcb_remove3() */
718     LCB_CALLBACK_UNLOCK, /**< lcb_unlock3() */
719     LCB_CALLBACK_STATS, /**< lcb_stats3() */
720     LCB_CALLBACK_VERSIONS, /**< lcb_server_versions3() */
721     LCB_CALLBACK_VERBOSITY, /**< lcb_server_verbosity3() */
722     LCB_CALLBACK_FLUSH, /**< lcb_flush3() */
723     LCB_CALLBACK_OBSERVE, /**< lcb_observe3_ctxnew() */
724     LCB_CALLBACK_GETREPLICA, /**< lcb_rget3() */
725     LCB_CALLBACK_ENDURE, /**< lcb_endure3_ctxnew() */
726     LCB_CALLBACK_HTTP, /**< lcb_http3() */
727     LCB_CALLBACK_CBFLUSH, /**< lcb_cbflush3() */
728     LCB_CALLBACK_OBSEQNO, /**< For lcb_observe_seqno3() */
729     LCB_CALLBACK_STOREDUR, /** <for lcb_storedur3() */
730     LCB_CALLBACK_SDLOOKUP,
731     LCB_CALLBACK_SDMUTATE,
732     LCB_CALLBACK_NOOP, /**< lcb_noop3() */
733     LCB_CALLBACK_PING, /**< lcb_ping3() */
734     LCB_CALLBACK_DIAG, /**< lcb_diag() */
735     LCB_CALLBACK__MAX /* Number of callbacks */
736 } lcb_CALLBACKTYPE;
737 
738 /* The following callback types cannot be set using lcb_install_callback3(),
739  * however, their value is passed along as the second argument of their
740  * respective callbacks. This allows you to still use the same callback,
741  * differentiating their meaning by the type. */
742 
743 /** Callback type for views (cannot be used for lcb_install_callback3()) */
744 #define LCB_CALLBACK_VIEWQUERY -1
745 
746 /** Callback type for N1QL (cannot be used for lcb_install_callback3()) */
747 #define LCB_CALLBACK_N1QL -2
748 
749 /** Callback type for N1QL index management (cannot be used for lcb_install_callback3()) */
750 #define LCB_CALLBACK_IXMGMT -3
751 
752 /** Callback type for Analytics (cannot be used for lcb_install_callback3()) */
753 #define LCB_CALLBACK_ANALYTICS -4
754 /**
755  * Callback invoked for responses.
756  * @param instance The handle
757  * @param cbtype The type of callback - or in other words, the type of operation
758  * this callback has been invoked for.
759  * @param resp The response for the operation. Depending on the operation this
760  * response structure should be casted into a more specialized type.
761  */
762 typedef void (*lcb_RESPCALLBACK)
763         (lcb_t instance, int cbtype, const lcb_RESPBASE* resp);
764 
765 /**
766  * @committed
767  *
768  * Install a new-style callback for an operation. The callback will be invoked
769  * with the relevant response structure.
770  *
771  * @param instance the handle
772  * @param cbtype the type of operation for which this callback should be installed.
773  *        The value should be one of the lcb_CALLBACKTYPE constants
774  * @param cb the callback to install
775  * @return the old callback
776  *
777  * @note LCB_CALLBACK_DEFAULT is initialized to the default handler which proxies
778  * back to the older 2.x callbacks. If you set `cbtype` to LCB_CALLBACK_DEFAULT
779  * then your `2.x` callbacks _will not work_.
780  *
781  * @note The old callback may be `NULL`. It is usually not an error to have a
782  * `NULL` callback installed. If the callback is `NULL`, then the default callback
783  * invocation pattern will take place (as desribed above). However it is an error
784  * to set the default callback to `NULL`.
785  */
786 LIBCOUCHBASE_API
787 lcb_RESPCALLBACK
788 lcb_install_callback3(lcb_t instance, int cbtype, lcb_RESPCALLBACK cb);
789 
790 /**
791  * @committed
792  *
793  * Get the current callback installed as `cbtype`. Note that this does not
794  * perform any kind of resolution (as described in lcb_install_callback3) and
795  * will only return a non-`NULL` value if a callback had specifically been
796  * installed via lcb_install_callback3() with the given `cbtype`.
797  *
798  * @param instance the handle
799  * @param cbtype the type of callback to retrieve
800  * @return the installed callback for the type.
801  */
802 LIBCOUCHBASE_API
803 lcb_RESPCALLBACK
804 lcb_get_callback3(lcb_t instance, int cbtype);
805 
806 /**
807  * Returns the type of the callback as a string.
808  * This function is helpful for debugging and demonstrative processes.
809  * @param cbtype the type of the callback (the second argument to the callback)
810  * @return a string describing the callback type
811  */
812 LIBCOUCHBASE_API
813 const char *
814 lcb_strcbtype(int cbtype);
815 
816 /**@}*/
817 
818 /**
819  * @ingroup lcb-kv-api
820  * @defgroup lcb-get Read
821  * @brief Retrieve a document from the cluster
822  * @addtogroup lcb-get
823  * @{
824  */
825 
826 /**
827  * If this bit is set in lcb_CMDGET::cmdflags then the expiry time is cleared if
828  * lcb_CMDGET::exptime is 0. This allows get-and-touch with an expiry of 0.
829  */
830 #define LCB_CMDGET_F_CLEAREXP (1<<16)
831 
832 /**@brief Command for retrieving a single item
833  *
834  * @see lcb_get3()
835  * @see lcb_RESPGET
836  *
837  * @note The #cas member should be set to 0 for this operation. If the #cas is
838  * not 0, lcb_get3() will fail with ::LCB_OPTIONS_CONFLICT.
839  *
840  * ### Use of the `exptime` field
841  *
842  * <ul>
843  * <li>Get And Touch:
844  *
845  * It is possible to retrieve an item and concurrently modify its expiration
846  * time (thus keeping it "alive"). The item's expiry time can be set using
847  * the #exptime field.
848  * </li>
849  *
850  * <li>Lock
851  * If the #lock field is set to non-zero, the #exptime field indicates the amount
852  * of time the lock should be held for
853  * </li>
854  * </ul>
855  */
856 typedef struct {
857     LCB_CMD_BASE;
858     /**If set to true, the `exptime` field inside `options` will take to mean
859      * the time the lock should be held. While the lock is held, other operations
860      * trying to access the key will fail with an `LCB_ETMPFAIL` error. The
861      * item may be unlocked either via `lcb_unlock3()` or via a mutation
862      * operation with a supplied CAS
863      */
864     int lock;
865 } lcb_CMDGET;
866 
867 /** @brief Response structure when retrieving a single item */
868 typedef struct {
869     LCB_RESP_BASE
870     const void *value; /**< Value buffer for the item */
871     lcb_SIZE nvalue; /**< Length of value */
872     void* bufh;
873     lcb_datatype_t datatype; /**< @internal */
874     lcb_U32 itmflags; /**< User-defined flags for the item */
875 } lcb_RESPGET;
876 
877 /**
878  * @committed
879  *
880  * @brief Spool a single get operation
881  * @param instance the handle
882  * @param cookie a pointer to be associated with the command
883  * @param cmd the command structure
884  * @return LCB_SUCCESS if successful, an error code otherwise
885  *
886  * @par Request
887  * @code{.c}
888  * lcb_CMDGET cmd = { 0 };
889  * LCB_CMD_SET_KEY(&cmd, "Hello", 5);
890  * lcb_get3(instance, cookie, &cmd);
891  * @endcode
892  *
893  * @par Response
894  * @code{.c}
895  * lcb_install_callback3(instance, LCB_CALLBACK_GET, get_callback);
896  * static void get_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb) {
897  *     const lcb_RESPGET *resp = (const lcb_RESPGET*)rb;
898  *     printf("Got response for key: %.*s\n", (int)resp->key, resp->nkey);
899  *
900  *     if (resp->rc != LCB_SUCCESS) {
901  *         printf("Couldn't get item: %s\n", lcb_strerror(NULL, resp->rc));
902  *     } else {
903  *         printf("Got value: %.*s\n", (int)resp->nvalue, resp->value);
904  *         printf("Got CAS: 0x%llx\n", resp->cas);
905  *         printf("Got item/formatting flags: 0x%x\n", resp->itmflags);
906  *     }
907  * }
908  *
909  * @endcode
910  *
911  * @par Errors
912  * @cb_err ::LCB_KEY_ENOENT if the item does not exist in the cluster
913  * @cb_err ::LCB_ETMPFAIL if the lcb_CMDGET::lock option was set but the item
914  * was already locked. Note that this error may also be returned (as a generic
915  * error) if there is a resource constraint within the server itself.
916  */
917 LIBCOUCHBASE_API
918 lcb_error_t
919 lcb_get3(lcb_t instance, const void *cookie, const lcb_CMDGET *cmd);
920 /**@}*/
921 
922 /**
923  * @ingroup lcb-kv-api
924  * @defgroup lcb-get-replica Read (Replica)
925  * @brief Retrieve a document from a replica if it cannot be fetched from the
926  * primary
927  * @addtogroup lcb-get-replica
928  * @{
929  */
930 
931 
932 /**@brief Select get-replica mode
933  * @see lcb_rget3_cmd_t */
934 typedef enum {
935     /**Query all the replicas sequentially, retrieving the first successful
936      * response */
937     LCB_REPLICA_FIRST = 0x00,
938 
939     /**Query all the replicas concurrently, retrieving all the responses*/
940     LCB_REPLICA_ALL = 0x01,
941 
942     /**Query the specific replica specified by the
943      * lcb_rget3_cmd_t#index field */
944     LCB_REPLICA_SELECT = 0x02
945 } lcb_replica_t;
946 
947 /**
948  * @brief Command for requesting an item from a replica
949  * @note The `options.exptime` and `options.cas` fields are ignored for this
950  * command.
951  *
952  * This structure is similar to @ref lcb_RESPGET with the addition of an
953  * `index` and `strategy` field which allow you to control and select how
954  * many replicas are queried.
955  *
956  * @see lcb_rget3(), lcb_RESPGET
957  */
958 typedef struct {
959     LCB_CMD_BASE;
960     /**
961      * Strategy for selecting a replica. The default is ::LCB_REPLICA_FIRST
962      * which results in the client trying each replica in sequence until a
963      * successful reply is found, and returned in the callback.
964      *
965      * ::LCB_REPLICA_FIRST evaluates to 0.
966      *
967      * Other options include:
968      * <ul>
969      * <li>::LCB_REPLICA_ALL - queries all replicas concurrently and dispatches
970      * a callback for each reply</li>
971      * <li>::LCB_REPLICA_SELECT - queries a specific replica indicated in the
972      * #index field</li>
973      * </ul>
974      *
975      * @note When ::LCB_REPLICA_ALL is selected, the callback will be invoked
976      * multiple times, one for each replica. The final callback will have the
977      * ::LCB_RESP_F_FINAL bit set in the lcb_RESPBASE::rflags field. The final
978      * response will also contain the response from the last replica to
979      * respond.
980      */
981     lcb_replica_t strategy;
982 
983     /**
984      * Valid only when #strategy is ::LCB_REPLICA_SELECT, specifies the replica
985      * index number to query. This should be no more than `nreplicas-1`
986      * where `nreplicas` is the number of replicas the bucket is configured with.
987      */
988     int index;
989 } lcb_CMDGETREPLICA;
990 
991 /**@committed
992  *
993  * @brief Spool a single get-with-replica request
994  * @param instance
995  * @param cookie
996  * @param cmd
997  * @return LCB_SUCCESS on success, error code otherwise.
998  *
999  * When a response is received, the callback installed for ::LCB_CALLBACK_GETREPLICA
1000  * will be invoked. The response will be an @ref lcb_RESPGET pointer.
1001  *
1002  * ### Request
1003  * @code{.c}
1004  * lcb_CMDGETREPLICA cmd = { 0 };
1005  * LCB_CMD_SET_KEY(&cmd, "key", 3);
1006  * lcb_rget3(instance, cookie, &cmd);
1007  * @endcode
1008  *
1009  * ### Response
1010  * @code{.c}
1011  * lcb_install_callback3(instance, LCB_CALLBACK_GETREPLICA, rget_callback);
1012  * static void rget_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
1013  * {
1014  *     const lcb_RESPGET *resp = (const lcb_RESPGET *)rb;
1015  *     printf("Got Get-From-Replica response for %.*s\n", (int)resp->key, resp->nkey);
1016  *     if (resp->rc == LCB_SUCCESS) {
1017  *         printf("Got response: %.*s\n", (int)resp->value, resp->nvalue);
1018  *     else {
1019  *         printf("Couldn't retrieve: %s\n", lcb_strerror(NULL, resp->rc));
1020  *     }
1021  * }
1022  * @endcode
1023  *
1024  * @warning As this function queries a replica node for data it is possible
1025  * that the returned document may not reflect the latest document in the server.
1026  *
1027  * @warning This function should only be used in cases where a normal lcb_get3()
1028  * has failed, or where there is reason to believe it will fail. Because this
1029  * function may query more than a single replica it may cause additional network
1030  * and server-side CPU load. Use sparingly and only when necessary.
1031  *
1032  * @cb_err ::LCB_KEY_ENOENT if the key is not found on the replica(s),
1033  * ::LCB_NO_MATCHING_SERVER if there are no replicas (either configured or online),
1034  * or if the given replica
1035  * (if lcb_CMDGETREPLICA::strategy is ::LCB_REPLICA_SELECT) is not available or
1036  * is offline.
1037  */
1038 LIBCOUCHBASE_API
1039 lcb_error_t
1040 lcb_rget3(lcb_t instance, const void *cookie, const lcb_CMDGETREPLICA *cmd);
1041 /**@}*/
1042 
1043 /**
1044  * @ingroup lcb-kv-api
1045  * @defgroup lcb-store Create/Update
1046  * @brief Set the value of a document
1047  * @addtogroup lcb-store
1048  * @{
1049  */
1050 
1051 /**
1052  * @brief Values for lcb_CMDSTORE::operation
1053  *
1054  * Storing an item in couchbase is only one operation with a different
1055  * set of attributes / constraints.
1056  */
1057 typedef enum {
1058     /**
1059      * Will cause the operation to fail if the key already exists in the
1060      * cluster.
1061      */
1062     LCB_ADD = 0x01,
1063 
1064     /**
1065      * Will cause the operation to fail _unless_ the key already exists in the
1066      * cluster.
1067      */
1068     LCB_REPLACE = 0x02,
1069 
1070     /** Unconditionally store the item in the cluster */
1071     LCB_SET = 0x03,
1072 
1073     /**
1074      * The default storage mode. This constant was added in version 2.6.2 for
1075      * the sake of maintaining a default storage mode, eliminating the need
1076      * for simple storage operations to explicitly define
1077      * lcb_CMDSTORE::operation. Behaviorally it is identical to @ref LCB_SET
1078      * in that it will make the server unconditionally store the item, whether
1079      * it exists or not.
1080      */
1081     LCB_UPSERT = 0x00,
1082 
1083     /**
1084      * Rather than setting the contents of the entire document, take the value
1085      * specified in lcb_CMDSTORE::value and _append_ it to the existing bytes in
1086      * the value.
1087      */
1088     LCB_APPEND = 0x04,
1089 
1090     /**
1091      * Like ::LCB_APPEND, but prepends the new value to the existing value.
1092      */
1093     LCB_PREPEND = 0x05
1094 } lcb_storage_t;
1095 
1096 /**@brief
1097  *
1098  * Command for storing an item to the server. This command must contain the
1099  * key to mutate, the value which should be set (or appended/prepended) in the
1100  * lcb_CMDSTORE::value field (see LCB_CMD_SET_VALUE()) and the operation indicating
1101  * the mutation type (lcb_CMDSTORE::operation).
1102  *
1103  * @warning #exptime *cannot* be used with #operation set to @ref LCB_APPEND
1104  * or @ref LCB_PREPEND.
1105  */
1106 typedef struct {
1107     LCB_CMD_BASE;
1108 
1109     /**
1110      * Value to store on the server. The value may be set using the
1111      * LCB_CMD_SET_VALUE() or LCB_CMD_SET_VALUEIOV() API
1112      */
1113     lcb_VALBUF value;
1114 
1115     /**
1116      * Format flags used by clients to determine the underlying encoding of
1117      * the value. This value is also returned during retrieval operations in the
1118      * lcb_RESPGET::itmflags field
1119      */
1120     lcb_U32 flags;
1121 
1122     /** Do not set this value for now */
1123     lcb_datatype_t datatype;
1124 
1125     /** Controls *how* the operation is perfomed. See the documentation for
1126      * @ref lcb_storage_t for the options. There is no default value for this
1127      * field.
1128      */
1129     lcb_storage_t operation;
1130 } lcb_CMDSTORE;
1131 
1132 /**
1133  * @brief Response structure for lcb_store3()
1134  */
1135 typedef struct {
1136     LCB_RESP_BASE
1137 
1138     /** The type of operation which was performed */
1139     lcb_storage_t op;
1140 } lcb_RESPSTORE;
1141 
1142 /**
1143  * @committed
1144  *
1145  * @brief Set the value buffer for the command. This may be used when the new
1146  * value is a single contiguous buffer.
1147  *
1148  * @param scmd an lcb_CMDSTORE pointer
1149  * @param valbuf the buffer for the value
1150  * @param vallen the length of the buffer
1151  *
1152  * The buffer needs to remain valid only until the command is passed to the
1153  * lcb_store3() function.
1154  */
1155 #define LCB_CMD_SET_VALUE(scmd, valbuf, vallen) do { \
1156     (scmd)->value.vtype = LCB_KV_COPY; \
1157     (scmd)->value.u_buf.contig.bytes = valbuf; \
1158     (scmd)->value.u_buf.contig.nbytes = vallen; \
1159 } while (0);
1160 
1161 /**
1162  * @committed
1163  *
1164  * @brief Set value from a series of input buffers. This may be used when the
1165  * input buffer is not contiguous. Using this call eliminates the need for
1166  * creating a temporary contiguous buffer in which to store the value.
1167  *
1168  * @param scmd the command which needs a value
1169  * @param iovs an array of @ref lcb_IOV structures
1170  * @param niovs number of items in the array.
1171  *
1172  * The buffers (and the IOV array itself)
1173  * need to remain valid only until the scheduler function is called. Once the
1174  * scheduling function is called, the buffer contents are copied into the
1175  * library's internal buffers.
1176  */
1177 #define LCB_CMD_SET_VALUEIOV(scmd, iovs, niovs) do { \
1178     (scmd)->value.vtype = LCB_KV_IOVCOPY; \
1179     (scmd)->value.u_buf.multi.iov = iovs; \
1180     (scmd)->value.u_buf.multi.niov = niovs; \
1181 } while (0);
1182 
1183 /**
1184  * @committed
1185  * @brief Schedule a single storage request
1186  * @param instance the handle
1187  * @param cookie pointer to associate with the command
1188  * @param cmd the command structure
1189  * @return LCB_SUCCESS on success, error code on failure
1190  *
1191  * ### Request
1192  *
1193  * @code{.c}
1194  * lcb_CMDSTORE cmd = { 0 };
1195  * LCB_CMD_SET_KEY(&cmd, "Key", 3);
1196  * LCB_CMD_SET_VALUE(&cmd, "value", 5);
1197  * cmd.operation = LCB_ADD; // Only create if it does not exist
1198  * cmd.exptime = 60; // expire in a minute
1199  * lcb_store3(instance, cookie, &cmd);
1200  * lcb_wait3(instance, LCB_WAIT_NOCHECK);
1201  * @endcode
1202  *
1203  * ### Response
1204  * @code{.c}
1205  * lcb_install_callback3(instance, LCB_CALLBACK_STORE, store_callback);
1206  * void store_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
1207  * {
1208  *     if (rb->rc == LCB_SUCCESS) {
1209  *         printf("Store success: CAS=%llx\n", rb->cas);
1210  *     } else {
1211  *         printf("Store failed: %s\n", lcb_strerror(NULL, rb->rc);
1212  *     }
1213  * }
1214  * @endcode
1215  *
1216  * Operation-specific error codes include:
1217  * @cb_err ::LCB_KEY_ENOENT if ::LCB_REPLACE was used and the key does not exist
1218  * @cb_err ::LCB_KEY_EEXISTS if ::LCB_ADD was used and the key already exists
1219  * @cb_err ::LCB_KEY_EEXISTS if the CAS was specified (for an operation other
1220  *          than ::LCB_ADD) and the item exists on the server with a different
1221  *          CAS
1222  * @cb_err ::LCB_KEY_EEXISTS if the item was locked and the CAS supplied did
1223  * not match the locked item's CAS (or if no CAS was supplied)
1224  * @cb_err ::LCB_NOT_STORED if an ::LCB_APPEND or ::LCB_PREPEND operation was
1225  * performed and the item did not exist on the server.
1226  * @cb_err ::LCB_E2BIG if the size of the value exceeds the cluster per-item
1227  *         value limit (currently 20MB).
1228  *
1229  *
1230  * @note After a successful store operation you can use lcb_endure3_ctxnew()
1231  * to wait for the item to be persisted and/or replicated to other nodes.
1232  */
1233 LIBCOUCHBASE_API
1234 lcb_error_t
1235 lcb_store3(lcb_t instance, const void *cookie, const lcb_CMDSTORE *cmd);
1236 /**@}*/
1237 
1238 /**
1239  * @ingroup lcb-kv-api
1240  * @defgroup lcb-remove Delete
1241  * @brief Remove documents from the cluster
1242  * @addtogroup lcb-remove
1243  * @{
1244  */
1245 
1246 /**@brief
1247  * Command for removing an item from the server
1248  * @note The lcb_CMDREMOVE::exptime field here does nothing.
1249  *
1250  * The lcb_CMDREMOVE::cas field may be
1251  * set to the last CAS received from a previous operation if you wish to
1252  * ensure the item is removed only if it has not been mutated since the last
1253  * retrieval
1254  */
1255 typedef lcb_CMDBASE lcb_CMDREMOVE;
1256 
1257 /**@brief
1258  * Response structure for removal operation. The lcb_RESPREMOVE::cas  field
1259  * may be used to check that it no longer exists on any node's storage
1260  * using the lcb_endure3_ctxnew() function. You can also use the
1261  * @ref lcb_MUTATION_TOKEN (via lcb_resp_get_mutation_token)
1262  *
1263  * The lcb_RESPREMOVE::rc field may be set to ::LCB_KEY_ENOENT if the item does
1264  * not exist, or ::LCB_KEY_EEXISTS if a CAS was specified and the item has since
1265  * been mutated.
1266  */
1267 typedef lcb_RESPBASE lcb_RESPREMOVE;
1268 
1269 /**@committed
1270  * @brief Spool a removal of an item
1271  * @param instance the handle
1272  * @param cookie pointer to associate with the request
1273  * @param cmd the command
1274  * @return LCB_SUCCESS on success, other code on failure
1275  *
1276  * ### Request
1277  * @code{.c}
1278  * lcb_CMDREMOVE cmd = { 0 };
1279  * LCB_CMD_SET_KEY(&cmd, "deleteme", strlen("deleteme"));
1280  * lcb_remove3(instance, cookie, &cmd);
1281  * @endcode
1282  *
1283  * ### Response
1284  * @code{.c}
1285  * lcb_install_callback3(instance, LCB_CALLBACK_REMOVE, rm_callback);
1286  * void rm_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
1287  * {
1288  *     printf("Key: %.*s...", (int)resp->nkey, resp->key);
1289  *     if (rb->rc != LCB_SUCCESS) {
1290  *         printf("Failed to remove item!: %s\n", lcb_strerror(NULL, rb->rc));
1291  *     } else {
1292  *         printf("Removed item!\n");
1293  *     }
1294  * }
1295  * @endcode
1296  *
1297  * The following operation-specific error codes are returned in the callback
1298  * @cb_err ::LCB_KEY_ENOENT if the key does not exist
1299  * @cb_err ::LCB_KEY_EEXISTS if the CAS was specified and it does not match the
1300  *         CAS on the server
1301  * @cb_err ::LCB_KEY_EEXISTS if the item was locked and no CAS (or an incorrect
1302  *         CAS) was specified.
1303  *
1304  */
1305 LIBCOUCHBASE_API
1306 lcb_error_t
1307 lcb_remove3(lcb_t instance, const void *cookie, const lcb_CMDREMOVE * cmd);
1308 /**@}*/
1309 
1310 /**
1311  * @ingroup lcb-kv-api
1312  * @defgroup lcb-mctx MULTICMD API
1313  * @addtogroup lcb-mctx
1314  * @{
1315  */
1316 /**
1317  * Multi Command Context API
1318  * Some commands (notably, OBSERVE and its higher level equivalent, endue)
1319  * are handled more efficiently at the cluster side by stuffing multiple
1320  * items into a single packet.
1321  *
1322  * This structure defines three function pointers to invoke. The #addcmd()
1323  * function will add a new command to the current packet, the #done()
1324  * function will schedule the packet(s) into the current scheduling context
1325  * and the #fail() function will destroy the context without progressing
1326  * further.
1327  *
1328  * Some commands will return an lcb_MULTICMD_CTX object to be used for this
1329  * purpose:
1330  *
1331  * @code{.c}
1332  * lcb_MUTLICMD_CTX *ctx = lcb_observe3_ctxnew(instance);
1333  *
1334  * lcb_CMDOBSERVE cmd = { 0 };
1335  * LCB_CMD_SET_KEY(&cmd, "key1", strlen("key1"));
1336  * ctx->addcmd(ctx, &cmd);
1337  * LCB_CMD_SET_KEY(&cmd.key, "key2", strlen("key2"));
1338  * ctx->addcmd(ctx, &cmd);
1339  * LCB_CMD_SET_KEY(&cmd.key, "key3", strlen("key3"));
1340  * ctx->addcmd(ctx, &cmd);
1341  *
1342  * ctx->done(ctx);
1343  * lcb_wait(instance);
1344  * @endcode
1345  */
1346 typedef struct lcb_MULTICMD_CTX_st {
1347     /**
1348      * Add a command to the current context
1349      * @param ctx the context
1350      * @param cmd the command to add. Note that `cmd` may be a subclass of lcb_CMDBASE
1351      * @return LCB_SUCCESS, or failure if a command could not be added.
1352      */
1353     lcb_error_t (*addcmd)(struct lcb_MULTICMD_CTX_st *ctx, const lcb_CMDBASE *cmd);
1354 
1355     /**
1356      * Indicate that no more commands are added to this context, and that the
1357      * context should assemble the packets and place them in the current
1358      * scheduling context
1359      * @param ctx The multi context
1360      * @param cookie The cookie for all commands
1361      * @return LCB_SUCCESS if scheduled successfully, or an error code if there
1362      * was a problem constructing the packet(s).
1363      */
1364     lcb_error_t (*done)(struct lcb_MULTICMD_CTX_st *ctx, const void *cookie);
1365 
1366     /**
1367      * Indicate that no more commands should be added to this context, and that
1368      * the context should not add its contents to the packet queues, but rather
1369      * release its resources. Called if you don't want to actually perform
1370      * the operations.
1371      * @param ctx
1372      */
1373     void (*fail)(struct lcb_MULTICMD_CTX_st *ctx);
1374 
1375 #ifdef LCB_TRACING
1376     /**
1377      * Associate parent tracing span with the group operation
1378      *
1379      * @param ctx The multi context
1380      * @param span Parent span
1381      */
1382     void (*setspan)(struct lcb_MULTICMD_CTX_st *ctx, lcbtrace_SPAN *span);
1383 #endif
1384 } lcb_MULTICMD_CTX;
1385 /**@}*/
1386 
1387 /**
1388  * @ingroup lcb-kv-api
1389  * @defgroup lcb-durability Durability
1390  * @brief Ensure persistence and mutation of documents
1391  * @addtogroup lcb-durability
1392  * @{
1393  */
1394 
1395 /**
1396  * @name Wait for a mutation to be persisted/replicated
1397  * @{
1398  */
1399 
1400 /**
1401  * Type of durability polling to use.
1402  */
1403 typedef enum {
1404     /**
1405      * Use the preferred durability. If ::LCB_CNTL_FETCH_MUTATION_TOKENS is
1406      * enabled and the server version is 4.0 or greater then ::LCB_DURABILITY_MODE_SEQNO
1407      * is used. Otherwise ::LCB_DURABILITY_MODE_CAS is used.
1408      */
1409     LCB_DURABILITY_MODE_DEFAULT = 0,
1410 
1411     /**
1412      * Explicitly request CAS-based durability. This is done by checking the
1413      * CAS of the item on each server with the item specified in the input.
1414      * The durability operation is considered complete when all items' CAS
1415      * values match. If the CAS value on the master node changes then the
1416      * durability operation will fail with ::LCB_KEY_EEXISTS.
1417      *
1418      * @note
1419      * CAS may change either because of a failover or because of another
1420      * subsequent mutation. These scenarios are possible (though unlikely).
1421      * The ::LCB_DURABILITY_MODE_SEQNO mode is not subject to these constraints.
1422      */
1423     LCB_DURABILITY_MODE_CAS,
1424 
1425     /**
1426      * Use sequence-number based polling. This is done by checking the current
1427      * "mutation sequence number" for the given mutation. To use this mode
1428      * either an explicit @ref lcb_MUTATION_TOKEN needs to be passed, or
1429      * the ::LCB_CNTL_DURABILITY_MUTATION_TOKENS should be set, allowing
1430      * the caching of the latest mutation token for each vBucket.
1431      */
1432     LCB_DURABILITY_MODE_SEQNO
1433 } lcb_DURMODE;
1434 
1435 /** @brief Options for lcb_endure3_ctxnew() */
1436 typedef struct {
1437     /**
1438      * Upper limit in microseconds from the scheduling of the command. When
1439      * this timeout occurs, all remaining non-verified keys will have their
1440      * callbacks invoked with @ref LCB_ETIMEDOUT.
1441      *
1442      * If this field is not set, the value of @ref LCB_CNTL_DURABILITY_TIMEOUT
1443      * will be used.
1444      */
1445     lcb_U32 timeout;
1446 
1447     /**
1448      * The durability check may involve more than a single call to observe - or
1449      * more than a single packet sent to a server to check the key status. This
1450      * value determines the time to wait (in microseconds)
1451      * between multiple probes for the same server.
1452      * If not set, the @ref LCB_CNTL_DURABILITY_INTERVAL will be used
1453      * instead.
1454      */
1455     lcb_U32 interval;
1456 
1457     /**
1458      * how many nodes the key should be persisted to (including master).
1459      * If set to 0 then persistence will not be checked. If set to a large
1460      * number (i.e. UINT16_MAX) and #cap_max is also set, will be set to the
1461      * maximum number of nodes to which persistence is possible (which will
1462      * always contain at least the master node).
1463      *
1464      * The maximum valid value for this field is
1465      * 1 + the total number of configured replicas for the bucket which are part
1466      * of the cluster. If this number is higher then it will either be
1467      * automatically capped to the maximum available if (#cap_max is set) or
1468      * will result in an ::LCB_DURABILITY_ETOOMANY error.
1469      */
1470     lcb_U16 persist_to;
1471 
1472     /**
1473      * how many nodes the key should be persisted to (excluding master).
1474      * If set to 0 then replication will not be checked. If set to a large
1475      * number (i.e. UINT16_MAX) and #cap_max is also set, will be set to the
1476      * maximum number of nodes to which replication is possible (which may
1477      * be 0 if the bucket is not configured for replicas).
1478      *
1479      * The maximum valid value for this field is the total number of configured
1480      * replicas which are part of the cluster. If this number is higher then
1481      * it will either be automatically capped to the maximum available
1482      * if (#cap_max is set) or will result in an ::LCB_DURABILITY_ETOOMANY
1483      * error.
1484      * */
1485     lcb_U16 replicate_to;
1486 
1487     /**
1488      * this flag inverts the sense of the durability check and ensures that
1489      * the key does *not* exist. This should be used if checking durability
1490      * after an lcb_remove3() operation.
1491      */
1492     lcb_U8 check_delete;
1493 
1494     /**
1495      * If replication/persistence requirements are excessive, cap to
1496      * the maximum available
1497      */
1498     lcb_U8 cap_max;
1499 
1500     /**
1501      * Set the polling method to use.
1502      * The value for this field should be one of the @ref lcb_DURMODE constants.
1503      */
1504     lcb_U8 pollopts;
1505 } lcb_DURABILITYOPTSv0;
1506 
1507 /**@brief Options for lcb_endure3_ctxnew() (wrapper)
1508  * @see lcb_DURABILITYOPTSv0 */
1509 typedef struct lcb_durability_opts_st {
1510     int version;
1511     union {
1512         lcb_DURABILITYOPTSv0 v0;
1513     } v;
1514 } lcb_durability_opts_t;
1515 
1516 /**Must specify this flag if using the 'mutation_token' field, as it was added in
1517  * a later version */
1518 #define LCB_CMDENDURE_F_MUTATION_TOKEN (1 << 16)
1519 
1520 /**@brief Command structure for endure.
1521  * If the lcb_CMDENDURE::cas field is specified, the operation will check and
1522  * verify that the CAS found on each of the nodes matches the CAS specified
1523  * and only then consider the item to be replicated and/or persisted to the
1524  * nodes. If the item exists on the master's cache with a different CAS then
1525  * the operation will fail
1526  */
1527 typedef struct {
1528     LCB_CMD_BASE;
1529     const lcb_MUTATION_TOKEN *mutation_token;
1530 } lcb_CMDENDURE;
1531 
1532 /**@brief Response structure for endure */
1533 typedef struct {
1534     LCB_RESP_BASE
1535     /**
1536      * Total number of polls (i.e. how many packets per server) did this
1537      * operation require
1538      */
1539     lcb_U16 nresponses;
1540 
1541     /**
1542      * Whether this item exists in the master in its current form. This can be
1543      * true even if #rc is not successful
1544      */
1545     lcb_U8 exists_master;
1546 
1547     /**
1548      * True if item was persisted on the master node. This may be true even if
1549      * #rc is not successful.
1550      */
1551     lcb_U8 persisted_master;
1552 
1553     /**
1554      * Total number of nodes (including master) on which this mutation has
1555      * been persisted. Valid even if #rc is not successful.
1556      */
1557     lcb_U8 npersisted;
1558 
1559     /**
1560      * Total number of replica nodes to which this mutation has been replicated.
1561      * Valid even if #rc is not successful.
1562      */
1563     lcb_U8 nreplicated;
1564 } lcb_RESPENDURE;
1565 
1566 /**
1567  * @committed
1568  *
1569  * @details
1570  * Ensure a key is replicated to a set of nodes
1571  *
1572  * The lcb_endure3_ctxnew() API is used to wait asynchronously until the item
1573  * have been persisted and/or replicated to at least the number of nodes
1574  * specified in the durability options.
1575  *
1576  * The command is implemented by sending a series of `OBSERVE` broadcasts
1577  * (see lcb_observe3_ctxnew()) to all the nodes in the cluster which are either
1578  * master or replica for a specific key. It polls repeatedly
1579  * (see lcb_DURABILITYOPTSv0::interval) until all the items have been persisted and/or
1580  * replicated to the number of nodes specified in the criteria, or the timeout
1581  * (aee lcb_DURABILITYOPTsv0::timeout) has been reached.
1582  *
1583  * The lcb_DURABILITYOPTSv0::persist_to and lcb_DURABILITYOPTS::replicate_to
1584  * control the number of nodes the item must be persisted/replicated to
1585  * in order for the durability polling to succeed.
1586  *
1587  * @brief Return a new command context for scheduling endure operations
1588  * @param instance the instance
1589  * @param options a structure containing the various criteria needed for
1590  * durability requirements
1591  * @param[out] err Error code if a new context could not be created
1592  * @return the new context, or NULL on error. Note that in addition to memory
1593  * allocation failure, this function might also return NULL because the `options`
1594  * structure contained bad values. Always check the `err` result.
1595  *
1596  * @par Scheduling Errors
1597  * The following errors may be encountered when scheduling:
1598  *
1599  * @cb_err ::LCB_DURABILITY_ETOOMANY if either lcb_DURABILITYOPTS::persist_to or
1600  * lcb_DURABILITYOPTS::replicate_to is too big. `err` may indicate this.
1601  * @cb_err ::LCB_DURABILITY_NO_MUTATION_TOKENS if no relevant mutation token
1602  * could be found for a given command (this is returned from the relevant
1603  * lcb_MULTICMD_CTX::addcmd call).
1604  * @cb_err ::LCB_DUPLICATE_COMMANDS if using CAS-based durability and the
1605  * same key was submitted twice to lcb_MULTICMD_CTX::addcmd(). This error is
1606  * returned from lcb_MULTICMD_CTX::done()
1607  *
1608  * @par Callback Errors
1609  * The following errors may be returned in the callback:
1610  * @cb_err ::LCB_ETIMEDOUT if the criteria could not be verified within the
1611  * accepted timeframe (see lcb_DURABILITYOPTSv0::timeout)
1612  * @cb_err ::LCB_KEY_EEXISTS if using CAS-based durability and the item's
1613  * CAS has been changed on the master node
1614  * @cb_err ::LCB_MUTATION_LOST if using sequence-based durability and the
1615  * server has detected that data loss has occurred due to a failover.
1616  *
1617  * @par Creating request context
1618  * @code{.c}
1619  * lcb_durability_opts_t dopts;
1620  * lcb_error_t rc;
1621  * memset(&dopts, 0, sizeof dopts);
1622  * dopts.v.v0.persist_to = -1;
1623  * dopts.v.v0.replicate_to = -1;
1624  * dopts.v.v0.cap_max = 1;
1625  * mctx = lcb_endure3_ctxnew(instance, &dopts, &rc);
1626  * // Check mctx != NULL and rc == LCB_SUCCESS
1627  * @endcode
1628  *
1629  * @par Adding keys - CAS
1630  * This can be used to add keys using CAS-based durability. This shows an
1631  * example within a store callback.
1632  * @code{.c}
1633  * lcb_RESPSTORE *resp = get_store_response();
1634  * lcb_CMDENDURE cmd = { 0 };
1635  * LCB_CMD_SET_KEY(&cmd, resp->key, resp->nkey);
1636  * cmd.cas = resp->cas;
1637  * rc = mctx->addcmd(mctx, (const lcb_CMDBASE*)&cmd);
1638  * rc = mctx->done(mctx, cookie);
1639  * @endcode
1640  *
1641  * @par Adding keys - explicit sequence number
1642  * Shows how to use an explicit sequence number as a basis for polling
1643  * @code{.c}
1644  * // during instance creation:
1645  * lcb_cntl_string(instance, "fetch_mutation_tokens", "true");
1646  * lcb_connect(instance);
1647  * // ...
1648  * lcb_RESPSTORE *resp = get_store_response();
1649  * lcb_CMDENDURE cmd = { 0 };
1650  * LCB_CMD_SET_KEY(&cmd, resp->key, resp->nkey);
1651  * cmd.mutation_token = &resp->mutation_token;
1652  * cmd.cmdflags |= LCB_CMDENDURE_F_MUTATION_TOKEN;
1653  * rc = mctx->addcmd(mctx, (const lcb_CMDBASE*)&cmd);
1654  * rc = mctx->done(mctx, cookie);
1655  * @endcode
1656  *
1657  * @par Adding keys - implicit sequence number
1658  * Shows how to use an implicit mutation token (internally tracked by the
1659  * library) for durability:
1660  * @code{.c}
1661  * // during instance creation
1662  * lcb_cntl_string(instance, "fetch_mutation_tokens", "true");
1663  * lcb_cntl_string(instance, "dur_mutation_tokens", "true");
1664  * lcb_connect(instance);
1665  * // ...
1666  * lcb_CMDENDURE cmd = { 0 };
1667  * LCB_CMD_SET_KEY(&cmd, "key", strlen("key"));
1668  * mctx->addcmd(mctx, (const lcb_CMDBASE*)&cmd);
1669  * mctx->done(mctx, cookie);
1670  * @endcode
1671  *
1672  * @par Response
1673  * @code{.c}
1674  * lcb_install_callback3(instance, LCB_CALLBACK_ENDURE, dur_callback);
1675  * void dur_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
1676  * {
1677  *     const lcb_RESPENDURE *resp = (const lcb_RESPENDURE*)rb;
1678  *     printf("Durability polling result for %.*s.. ", (int)resp->nkey, resp->key);
1679  *     if (resp->rc != LCB_SUCCESS) {
1680  *         printf("Failed: %s\n", lcb_strerror(NULL, resp->rc);
1681  *         return;
1682  *     }
1683  * }
1684  * @endcode
1685  */
1686 LIBCOUCHBASE_API
1687 lcb_MULTICMD_CTX *
1688 lcb_endure3_ctxnew(lcb_t instance,
1689     const lcb_durability_opts_t *options, lcb_error_t *err);
1690 
1691 /**
1692  * Command structure for lcb_storedur3()
1693  * This is much like @ref lcb_CMDSTORE, but also includes durability options.
1694  */
1695 typedef struct {
1696     LCB_CMD_BASE;
1697     lcb_VALBUF value; /**< @see lcb_CMDSTORE::value */
1698     lcb_U32 flags; /**< @see lcb_CMDSTORE::flags */
1699     lcb_datatype_t datatype; /**< @internal */
1700     lcb_storage_t operation; /**< @see lcb_CMDSTORE::operation */
1701 
1702     /**
1703      * Number of nodes to persist to. If negative, will be capped at the maximum
1704      * allowable for the current cluster.
1705      * @see lcb_DURABILITYOPTSv0::persist_to
1706      */
1707     char persist_to;
1708 
1709     /**
1710      * Number of nodes to replicate to. If negative, will be capped at the maximum
1711      * allowable for the current cluster.
1712      * @see lcb_DURABILITYOPTSv0::replicate_to
1713      */
1714     char replicate_to;
1715 } lcb_CMDSTOREDUR;
1716 
1717 /**
1718  * Response structure for `LCB_CALLBACK_STOREDUR.
1719  */
1720 typedef struct {
1721     LCB_RESP_BASE
1722     /** Internal durability response structure. This should never be NULL */
1723     const lcb_RESPENDURE *dur_resp;
1724 
1725     /**If the #rc field is not @ref LCB_SUCCESS, this field indicates
1726      * what failed. If this field is nonzero, then the store operation failed,
1727      * but the durability checking failed. If this field is zero then the
1728      * actual storage operation failed. */
1729     int store_ok;
1730 } lcb_RESPSTOREDUR;
1731 
1732 /**
1733  * @volatile
1734  *
1735  * Schedule a storage operation with subsequent durability checking.
1736  *
1737  * This is a compound of a logical lcb_store3() followed by an
1738  * lcb_endure3_ctxnew() upon success.
1739  */
1740 LIBCOUCHBASE_API
1741 lcb_error_t
1742 lcb_storedur3(lcb_t instance, const void *cookie, const lcb_CMDSTOREDUR *cmd);
1743 
1744 #define LCB_DURABILITY_VALIDATE_CAPMAX (1 << 1)
1745 
1746 /**
1747  * @committed
1748  *
1749  * Validate durability settings.
1750  *
1751  * This function will validate (and optionally modify) the settings. This is
1752  * helpful to ensure the durability options are valid _before_ issuing a command
1753  *
1754  * @param instance the instance
1755  *
1756  * @param[in,out] persist_to The desired number of servers to persist to.
1757  *  If the `CAPMAX` flag is set, on output this will contain the effective
1758  *  number of servers the item can be persisted to
1759  *
1760  * @param[in,out] replicate_to The desired number of servers to replicate to.
1761  *  If the `CAPMAX` flag is set, on output this will contain the effective
1762  *  number of servers the item can be replicated to
1763  *
1764  * @param options Options to use for validating. The only recognized option
1765  *  is currently `LCB_DURABILITY_VALIDATE_CAPMAX` which has the same semantics
1766  *  as lcb_DURABILITYOPTSv0::cap_max.
1767  *
1768  * @return LCB_SUCCESS on success
1769  * @return LCB_DURABILITY_ETOOMANY if the requirements exceed the number of
1770  *  servers currently available, and `CAPMAX` was not specifie
1771  * @return LCB_EINVAL if both `persist_to` and `replicate_to` are 0.
1772  */
1773 LIBCOUCHBASE_API
1774 lcb_error_t
1775 lcb_durability_validate(lcb_t instance,
1776     lcb_U16 *persist_to, lcb_U16 *replicate_to, int options);
1777 /**@} (NAME) */
1778 
1779 
1780 /**
1781  * @name Retrieve current persistence/replication status
1782  * @{
1783  */
1784 
1785 /**Set this bit in the cmdflags field to indicate that only the master node
1786  * should be contacted*/
1787 #define LCB_CMDOBSERVE_F_MASTER_ONLY (1 << 16)
1788 
1789 /**@brief Structure for an observe request.
1790  * To request the status from _only_ the master node of the key, set the
1791  * LCB_CMDOBSERVE_F_MASTERONLY bit inside the lcb_CMDOBSERVE::cmdflags field
1792  */
1793 typedef struct {
1794     LCB_CMD_BASE;
1795     /**For internal use: This determines the servers the command should be
1796      * routed to. Each entry is an index within the server. */
1797     const lcb_U16* servers_;
1798     size_t nservers_;
1799 } lcb_CMDOBSERVE;
1800 
1801 /**
1802  * @brief Possible statuses for keys in OBSERVE response
1803  */
1804 typedef enum {
1805     /** The item found in the memory, but not yet on the disk */
1806     LCB_OBSERVE_FOUND = 0x00,
1807     /** The item hit the disk */
1808     LCB_OBSERVE_PERSISTED = 0x01,
1809     /** The item missing on the disk and the memory */
1810     LCB_OBSERVE_NOT_FOUND = 0x80,
1811     /** No knowledge of the key :) */
1812     LCB_OBSERVE_LOGICALLY_DELETED = 0x81,
1813 
1814     LCB_OBSERVE_MAX = 0x82
1815 } lcb_observe_t;
1816 
1817 /**@brief Response structure for an observe command.
1818  * Note that the lcb_RESPOBSERVE::cas contains the CAS of the item as it is
1819  * stored within that specific server. The CAS may be incorrect or stale
1820  * unless lcb_RESPOBSERVE::ismaster is true.
1821  */
1822 typedef struct {
1823     LCB_RESP_BASE
1824     lcb_U8 status; /**<Bit set of flags */
1825     lcb_U8 ismaster; /**< Set to true if this response came from the master node */
1826     lcb_U32 ttp; /**<Unused. For internal requests, contains the server index */
1827     lcb_U32 ttr; /**<Unused */
1828 } lcb_RESPOBSERVE;
1829 
1830 /**
1831  * @brief Create a new multi context for an observe operation
1832  * @param instance the instance
1833  * @return a new multi command context, or NULL on allocation failure.
1834  * @committed
1835  *
1836  * Note that the callback for this command will be invoked multiple times,
1837  * one for each node. To determine when no more callbacks will be invoked,
1838  * check for the LCB_RESP_F_FINAL flag inside the lcb_RESPOBSERVE::rflags
1839  * field.
1840  *
1841  * @code{.c}
1842  * void callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPOBSERVE *resp)
1843  * {
1844  *   if (resp->rflags & LCB_RESP_F_FINAL) {
1845  *     return;
1846  *   }
1847  *
1848  *   printf("Got status for key %.*s\n", (int)resp->nkey, resp->key);
1849  *   printf("  Node Type: %s\n", resp->ismaster ? "MASTER" : "REPLICA");
1850  *   printf("  Status: 0x%x\n", resp->status);
1851  *   printf("  Current CAS: 0x%"PRIx64"\n", resp->cas);
1852  * }
1853  *
1854  * lcb_MULTICMD_CTX *mctx = lcb_observe3_ctxnew(instance);
1855  * lcb_CMDOBSERVE cmd = { 0 };
1856  * LCB_CMD_SET_KEY(&cmd, "key", 3);
1857  * mctx->addcmd(mctx, (lcb_CMDBASE *)&cmd);
1858  * mctx->done(mctx, cookie);
1859  * lcb_install_callback3(instance, LCB_CALLBACK_OBSERVE, (lcb_RESP_cb)callback);
1860  * @endcode
1861  *
1862  * @warning
1863  * Operations created by observe cannot be undone using lcb_sched_fail().
1864  */
1865 LIBCOUCHBASE_API
1866 lcb_MULTICMD_CTX *
1867 lcb_observe3_ctxnew(lcb_t instance);
1868 
1869 /**
1870  * @brief Command structure for lcb_observe_seqno3().
1871  * Note #key, #nkey, and #cas are not used in this command.
1872  */
1873 typedef struct {
1874     LCB_CMD_BASE;
1875     /**
1876      * Server index to target. The server index must be valid and must also
1877      * be either a master or a replica for the vBucket indicated in #vbid
1878      */
1879     lcb_U16 server_index;
1880     lcb_U16 vbid; /**< vBucket ID to query */
1881     lcb_U64 uuid; /**< UUID known to client which should be queried */
1882 } lcb_CMDOBSEQNO;
1883 
1884 /**
1885  * @brief Response structure for lcb_observe_seqno3()
1886  *
1887  * Note that #key, #nkey and #cas are empty because the operand is the relevant
1888  * mutation token fields in @ref lcb_CMDOBSEQNO
1889  */
1890 typedef struct {
1891     LCB_RESP_BASE
1892     lcb_U16 vbid; /**< vBucket ID (for potential mapping) */
1893     lcb_U16 server_index; /**< Input server index */
1894     lcb_U64 cur_uuid; /**< UUID for this vBucket as known to the server */
1895     lcb_U64 persisted_seqno; /**< Highest persisted sequence */
1896     lcb_U64 mem_seqno; /**< Highest known sequence */
1897 
1898     /**
1899      * In the case where the command's uuid is not the most current, this
1900      * contains the last known UUID
1901      */
1902     lcb_U64 old_uuid;
1903 
1904     /**
1905      * If #old_uuid is nonzero, contains the highest sequence number persisted
1906      * in the #old_uuid snapshot.
1907      */
1908     lcb_U64 old_seqno;
1909 } lcb_RESPOBSEQNO;
1910 
1911 /**
1912  * @volatile
1913  * @brief Get the persistence/replication status for a given mutation token
1914  * @param instance the handle
1915  * @param cookie callback cookie
1916  * @param cmd the command
1917  */
1918 LIBCOUCHBASE_API
1919 lcb_error_t
1920 lcb_observe_seqno3(lcb_t instance, const void *cookie, const lcb_CMDOBSEQNO *cmd);
1921 
1922 /**@} (Name: OBSERVE) */
1923 /**@} (Group: Durability) */
1924 
1925 /**
1926  * @ingroup lcb-public-api
1927  * @defgroup lcb-mutation-tokens Mutation Tokens
1928  *
1929  * @details Mutation Tokens are returned with mutations if
1930  * ::LCB_CNTL_FETCH_MUTATION_TOKENS is enabled (off by default). Mutation tokens
1931  * are largely of internal use, but can be used by N1QL queries and durability
1932  * requirement polling
1933  *
1934  * @addtogroup lcb-mutation-tokens
1935  * @{
1936  */
1937 
1938 /**
1939  * @brief
1940  * Structure representing a synchronization token. This token may be used
1941  * for durability operations and N1QL queries. The contents of this structure
1942  * should be considered opaque, and accessed via the various macros
1943  * @struct lcb_MUTATION_TOKEN
1944  */
1945 
1946 /** Get the vBucket UUID */
1947 #define LCB_MUTATION_TOKEN_ID(p) ((p)->uuid_)
1948 /** Get the sequence number */
1949 #define LCB_MUTATION_TOKEN_SEQ(p) ((p)->seqno_)
1950 /** Get the vBucket number itself */
1951 #define LCB_MUTATION_TOKEN_VB(p) ((p)->vbid_)
1952 /** Whether this mutation token has valid contents */
1953 #define LCB_MUTATION_TOKEN_ISVALID(p) \
1954     (p && !((p)->uuid_ == 0 && (p)->seqno_ == 0 && (p)->vbid_ == 0))
1955 
1956 /**
1957  * Retrieves the mutation token from the response structure
1958  * @param cbtype the type of callback invoked
1959  * @param rb the pointer to the response
1960  * @return The embedded mutation token, or NULL if the response does not have a
1961  *         mutation token. This may be either because the command does not support
1962  *         mutation tokens, or because they have been disabled at the connection
1963  *         level.
1964  */
1965 LIBCOUCHBASE_API
1966 const lcb_MUTATION_TOKEN *
1967 lcb_resp_get_mutation_token(int cbtype, const lcb_RESPBASE *rb);
1968 
1969 /**
1970  * @volatile
1971  *
1972  * Retrieves the last mutation token for a given key.
1973  * This relies on the @ref LCB_CNTL_DURABILITY_MUTATION_TOKENS option, and will
1974  * check the instance-level log to determine the latest MUTATION_TOKEN for
1975  * the given vBucket ID which the key maps to.
1976  *
1977  * @param instance the instance
1978  * @param kb The buffer representing the key. The type of the buffer (see
1979  * lcb_KEYBUF::type) may either be ::LCB_KV_COPY or ::LCB_KV_VBID
1980  * @param[out] errp Set to an error if this function returns NULL
1981  * @return The mutation token if successful, otherwise NULL.
1982  *
1983  * Getting the latest mutation token for a key:
1984  *
1985  * @code{.c}
1986  * lcb_KEYBUF kb;
1987  * kb.type = LCB_KV_COPY;
1988  * kb.contig.bytes = "Hello";
1989  * kv.config.nbytes = 5;
1990  * mt = lcb_get_mutation_token(instance, &kb, &rc);
1991  * @endcode
1992  *
1993  * Getting the latest mutation token for a vbucket:
1994  * @code{.c}
1995  * lcb_KEYBUF kb;
1996  * kv.type = LCB_KV_VBID;
1997  * kv.contig.nbytes = 543;
1998  * kv.config.bytes = NULL;
1999  * mt = lcb_get_mutation_token(instance, &kb, &rc);
2000  * @endcode
2001  *
2002  * Getting the mutation token for each vbucket
2003  * @code{.c}
2004  * size_t ii, nvb;
2005  * lcbvb_CONFIG *vbc;
2006  * lcb_cntl(instance, LCB_CNTL_GET, LCB_CNTL_VBCONFIG, &vbc);
2007  * nvb = vbucket_get_num_vbuckets(vbc);
2008  * for (ii = 0; ii < nvb; ii++) {
2009  *   lcb_KEYBUF kb;
2010  *   const lcb_MUTATION_TOKEN *mt;
2011  *   kb.type = LCB_KV_VBID;
2012  *   kb.contig.nbytes = ii;
2013  *   kb.config.bytes = NULL;
2014  *   mt = lcb_get_mutation_token(instance, &kb, &rc);
2015  * }
2016  * @endcode
2017  */
2018 LIBCOUCHBASE_API
2019 const lcb_MUTATION_TOKEN *
2020 lcb_get_mutation_token(lcb_t instance, const lcb_KEYBUF *kb, lcb_error_t *errp);
2021 
2022 /**@} (Group: Mutation Tokens) */
2023 
2024 /**
2025  * @ingroup lcb-kv-api
2026  * @defgroup lcb-counter Counters
2027  * @brief Manipulate the numeric content of a document
2028  * @details Counter operations treat the document being accessed as a numeric
2029  * value (the document should contain a parseable integer as its content). This
2030  * value may then be incremented or decremented.
2031  *
2032  * @addtogroup lcb-counter
2033  * @{
2034  */
2035 
2036 /**
2037  * @brief Command for counter operations.
2038  * @see lcb_counter3(), lcb_RESPCOUNTER.
2039  *
2040  * @warning You may only set the #exptime member if the #create member is set
2041  * to a true value. Setting `exptime` otherwise will cause the operation to
2042  * fail with @ref LCB_OPTIONS_CONFLICT
2043  *
2044  * @warning The #cas member should be set to 0 for this operation. As this
2045  * operation itself is atomic, specifying a CAS is not necessary.
2046  */
2047 typedef struct {
2048     LCB_CMD_BASE;
2049     /**Delta value. If this number is negative the item on the server is
2050      * decremented. If this number is positive then the item on the server
2051      * is incremented */
2052     lcb_int64_t delta;
2053     /**If the item does not exist on the server (and `create` is true) then
2054      * this will be the initial value for the item. */
2055     lcb_U64 initial;
2056     /**Boolean value. Create the item and set it to `initial` if it does not
2057      * already exist */
2058     int create;
2059 } lcb_CMDCOUNTER;
2060 
2061 /**
2062  * @brief Response structure for counter operations
2063  * @see lcb_counter3()
2064  */
2065 typedef struct {
2066     LCB_RESP_BASE
2067     /** Contains the _current_ value after the operation was performed */
2068     lcb_U64 value;
2069 } lcb_RESPCOUNTER;
2070 
2071 /**@committed
2072  * @brief Schedule single counter operation
2073  * @param instance the instance
2074  * @param cookie the pointer to associate with the request
2075  * @param cmd the command to use
2076  * @return LCB_SUCCESS on success, other error on failure
2077  *
2078  * @par Request
2079  * @code{.c}
2080  * lcb_CMDCOUNTER cmd = { 0 };
2081  * LCB_CMD_SET_KEY(&cmd, "counter", strlen("counter"));
2082  * cmd.delta = 1; // Increment by one
2083  * cmd.initial = 42; // Default value is 42 if it does not exist
2084  * cmd.exptime = 300; // Expire in 5 minutes
2085  * lcb_counter3(instance, NULL, &cmd);
2086  * lcb_wait3(instance, LCB_WAIT_NOCHECK);
2087  * @endcode
2088  *
2089  * @par Response
2090  * @code{.c}
2091  * lcb_install_callback3(instance, LCB_CALLBACKTYPE_COUNTER, counter_cb);
2092  * void counter_cb(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
2093  * {
2094  *     const lcb_RESPCOUNTER *resp = (const lcb_RESPCOUNTER *)rb;
2095  *     if (resp->rc == LCB_SUCCESS) {
2096  *         printf("Incremented counter for %.*s. Current value %llu\n",
2097  *                (int)resp->nkey, resp->key, resp->value);
2098  *     }
2099  * }
2100  * @endcode
2101  *
2102  * @par Callback Errors
2103  * In addition to generic errors, the following errors may be returned in the
2104  * callback (via lcb_RESPBASE::rc):
2105  *
2106  * @cb_err ::LCB_KEY_ENOENT if the counter doesn't exist
2107  * (and lcb_CMDCOUNTER::create was not set)
2108  * @cb_err ::LCB_DELTA_BADVAL if the existing document's content could not
2109  * be parsed as a number by the server.
2110  */
2111 LIBCOUCHBASE_API
2112 lcb_error_t
2113 lcb_counter3(lcb_t instance, const void *cookie, const lcb_CMDCOUNTER *cmd);
2114 /**@} (Group: Counter) */
2115 
2116 /**@ingroup lcb-kv-api
2117  * @defgroup lcb-lock Lock/Unlock
2118  * @details Documents may be locked and unlocked on the server. While a document
2119  * is locked, any attempt to modify it (or lock it again) will fail.
2120  *
2121  * @note Locks are not persistent across nodes (if a node fails over, the lock
2122  * is not transferred to a replica).
2123  * @note The recommended way to manage access and concurrency control for
2124  * documents in Couchbase is through the CAS (See lcb_CMDBASE::cas and
2125  * lcb_RESPBASE::cas), which can also be considered a form of opportunistic
2126  * locking.
2127  *
2128  * @par Locking an item
2129  * There is no exclusive function to lock an item. Locking an item is done
2130  * using @ref lcb_get3(), by setting the lcb_CMDGET::lock option to true.
2131  *
2132  * @addtogroup lcb-lock
2133  * @{
2134  */
2135 
2136 /**@brief Command for lcb_unlock3()
2137  * @attention lcb_CMDBASE::cas must be specified, or the operation will fail on
2138  * the server*/
2139 typedef lcb_CMDBASE lcb_CMDUNLOCK;
2140 
2141 /**@brief Response structure for an unlock command.
2142  * @note the lcb_RESPBASE::cas field does not contain the CAS of the item*/
2143 typedef lcb_RESPBASE lcb_RESPUNLOCK;
2144 
2145 /**
2146  * @committed
2147  * @brief
2148  * Unlock a previously locked item using lcb_CMDGET::lock
2149  *
2150  * @param instance the instance
2151  * @param cookie the context pointer to associate with the command
2152  * @param cmd the command containing the information about the locked key
2153  * @return LCB_SUCCESS if successful, an error code otherwise
2154  * @see lcb_get3()
2155  *
2156  * @par Request
2157  *
2158  * @code{.c}
2159  * void locked_callback(lcb_t, lcb_CALLBACKTYPE, const lcb_RESPBASE *resp) {
2160  *   lcb_CMDUNLOCK cmd = { 0 };
2161  *   LCB_CMD_SET_KEY(&cmd, resp->key, resp->nkey);
2162  *   cmd.cas = resp->cas;
2163  *   lcb_unlock3(instance, cookie, &cmd);
2164  * }
2165  *
2166  * @endcode
2167  */
2168 LIBCOUCHBASE_API
2169 lcb_error_t
2170 lcb_unlock3(lcb_t instance, const void *cookie, const lcb_CMDUNLOCK *cmd);
2171 /**@} (Group: Unlock) */
2172 
2173 /**@ingroup lcb-kv-api
2174  * @defgroup lcb-touch Touch/Expiry
2175  * @brief Modify or clear a document's expiration time
2176  * @details Couchbase allows documents to contain expiration times
2177  * (see lcb_CMDBASE::exptime). Most operations allow the expiry time to be
2178  * updated, however lcb_touch3() allows the exclusive update of the expiration
2179  * time without additional network overhead.
2180  *
2181  * @addtogroup lcb-touch
2182  * @{
2183  */
2184 
2185 /**
2186  * @brief Command structure for a touch request
2187  * @note The lcb_CMDTOUCH::cas field is ignored. The item's modification time
2188  * is always updated regardless if the CAS on the server differs.
2189  * The #exptime field is always used. If 0 then the expiry on the server is
2190  * cleared.
2191  */
2192 typedef lcb_CMDBASE lcb_CMDTOUCH;
2193 
2194 /**@brief Response structure for a touch request
2195  * @note the lcb_RESPTOUCH::cas field contains the current CAS of the item*/
2196 typedef lcb_RESPBASE lcb_RESPTOUCH;
2197 
2198 /**@committed
2199  * @brief Spool a touch request
2200  * @param instance the handle
2201  * @param cookie the pointer to associate with the request
2202  * @param cmd the command
2203  * @return LCB_SUCCESS on success, other error code on failure
2204  *
2205  * @par Request
2206  * @code{.c}
2207  * lcb_CMDTOUCH cmd = { 0 };
2208  * LCB_CMD_SET_KEY(&cmd, "keep_me", strlen("keep_me"));
2209  * cmd.exptime = 0; // Clear the expiration
2210  * lcb_touch3(instance, cookie, &cmd);
2211  * @endcode
2212  *
2213  * @par Response
2214  * @code{.c}
2215  * lcb_install_callback3(instance, LCB_CALLBACK_TOUCH, touch_callback);
2216  * void touch_callback(lcb_t instance, int cbtype, const lcb_RESPBASE *rb)
2217  * {
2218  *     if (rb->rc == LCB_SUCCESS) {
2219  *         printf("Touch succeeded\n");
2220  *     }
2221  * }
2222  * @endcode
2223  */
2224 LIBCOUCHBASE_API
2225 lcb_error_t
2226 lcb_touch3(lcb_t instance, const void *cookie, const lcb_CMDTOUCH *cmd);
2227 /**@} (Group: Touch) */
2228 /**@} (Group: KV API) */
2229 
2230 /**@ingroup lcb-public-api
2231  * @defgroup lcb-misc-cmds Miscellaneous Commands
2232  * @brief Additional miscellaneous commands which can be executed on the server.
2233  *
2234  * @addtogroup lcb-misc-cmds
2235  * @{
2236  */
2237 
2238 /**
2239  * @name Server Statistics
2240  * @{
2241  */
2242 
2243 /**
2244  * @brief Command structure for stats request
2245  * The lcb_CMDSTATS::key field should contain the statistics key, or be empty
2246  * if the default statistics are desired.
2247  * The #cmdflags field may contain the @ref LCB_CMDSTATS_F_KV flag.
2248  */
2249 typedef lcb_CMDBASE lcb_CMDSTATS;
2250 
2251 /**
2252  * The key is a stored item for which statistics should be retrieved. This
2253  * invokes the 'keystats' semantics. Note that when using _keystats_, a key
2254  * must be present, and must not have any spaces in it.
2255  */
2256 #define LCB_CMDSTATS_F_KV (1 << 16)
2257 
2258 /**@brief Response structure for cluster statistics.
2259  * The lcb_RESPSTATS::key field contains the statistic name (_not_ the same
2260  * as was passed in lcb_CMDSTATS::key which is the name of the statistical
2261  * _group_).*/
2262 typedef struct {
2263     LCB_RESP_BASE
2264     LCB_RESP_SERVER_FIELDS
2265     const char *value; /**< The value, if any, for the given statistic */
2266     lcb_SIZE nvalue; /**< Length of value */
2267 } lcb_RESPSTATS;
2268 
2269 /**@committed
2270  * @brief Schedule a request for statistics from the cluster.
2271  * @param instance the instance
2272  * @param cookie pointer to associate with the request
2273  * @param cmd the command
2274  * @return LCB_SUCCESS on success, other error code on failure.
2275  *
2276  * Note that the callback for this command is invoked an indeterminate amount
2277  * of times. The callback is invoked once for each statistic for each server.
2278  * When all the servers have responded with their statistics, a final callback
2279  * is delivered to the application with the LCB_RESP_F_FINAL flag set in the
2280  * lcb_RESPSTATS::rflags field. When this response is received no more callbacks
2281  * for this command shall be invoked.
2282  *
2283  * @par Request
2284  * @code{.c}
2285  * lcb_CMDSTATS cmd = { 0 };
2286  * // Using default stats, no further initialization
2287  * lcb_stats3(instance, fp, &cmd);
2288  * lcb_wait(instance);
2289  * @endcode
2290  *
2291  * @par Response
2292  * @code{.c}
2293  * lcb_install_callback3(instance, LCB_CALLBACK_STATS, stats_callback);
2294  * void stats_callback(lcb_t, int, const lcb_RESPBASE *rb)
2295  * {
2296  *     const lcb_RESPSTATS *resp = (const lcb_RESPSTATS*)rb;
2297  *     if (resp->key) {
2298  *         printf("Server %s: %.*s = %.*s\n", resp->server,
2299  *            (int)resp->nkey, resp->key,
2300  *            (int)resp->nvalue, resp->value);
2301  *     }
2302  *     if (resp->rflags & LCB_RESP_F_FINAL) {
2303  *       printf("No more replies remaining!\n");
2304  *     }
2305  * }
2306  * @endcode
2307  */
2308 LIBCOUCHBASE_API
2309 lcb_error_t
2310 lcb_stats3(lcb_t instance, const void *cookie, const lcb_CMDSTATS * cmd);
2311 /**@} (Name: Stats) */
2312 
2313 /**@name Server Versions
2314  * @warning This does not return the actual _Couchbase_ version but rather
2315  * the internal version of the memcached server.
2316  * @{
2317  */
2318 
2319 /**@brief Response structure for the version command */
2320 typedef struct {
2321     LCB_RESP_BASE
2322     LCB_RESP_SERVER_FIELDS
2323     const char *mcversion; /**< The version string */
2324     lcb_SIZE nversion; /**< Length of the version string */
2325 } lcb_RESPMCVERSION;
2326 
2327 /**
2328  * @volatile
2329  */
2330 LIBCOUCHBASE_API
2331 lcb_error_t
2332 lcb_server_versions3(lcb_t instance, const void *cookie, const lcb_CMDBASE * cmd);
2333 
2334 /**@} (Name: MCversion) */
2335 
2336 /**
2337  * @name Server Log Verbosity
2338  * @{
2339  */
2340 
2341 /** @brief `level` field for lcb_server_verbosity3 () */
2342 typedef enum {
2343     LCB_VERBOSITY_DETAIL = 0x00,
2344     LCB_VERBOSITY_DEBUG = 0x01,
2345     LCB_VERBOSITY_INFO = 0x02,
2346     LCB_VERBOSITY_WARNING = 0x03
2347 } lcb_verbosity_level_t;
2348 
2349 typedef struct {
2350     /* unused */
2351     LCB_CMD_BASE;
2352     const char *server;
2353     lcb_verbosity_level_t level;
2354 } lcb_CMDVERBOSITY;
2355 typedef lcb_RESPSERVERBASE lcb_RESPVERBOSITY;
2356 /**@volatile*/
2357 LIBCOUCHBASE_API
2358 lcb_error_t
2359 lcb_server_verbosity3(lcb_t instance, const void *cookie, const lcb_CMDVERBOSITY *cmd);
2360 /**@} (Name: Verbosity) */
2361 /**@} (Group: Misc) */
2362 
2363 /**
2364  * @ingroup lcb-public-api
2365  * @defgroup lcb-flush Flush
2366  * @brief Clear the contents of a bucket
2367  *
2368  * Flush is useful for development environments (for example clearing a bucket
2369  * before running tests).
2370  *
2371  * @addtogroup lcb-flush
2372  * @{
2373  */
2374 typedef lcb_CMDBASE lcb_CMDCBFLUSH;
2375 typedef lcb_RESPBASE lcb_RESPCBFLUSH;
2376 
2377 /**
2378  * @uncommitted
2379  *
2380  * Flush a bucket
2381  * This function will properly flush any type of bucket using the REST API
2382  * via HTTP. This may be used in a manner similar to the older lcb_flush3().
2383  *
2384  * The callback invoked under ::LCB_CALLBACK_CBFLUSH will be invoked with either
2385  * a success or failure status depending on the outcome of the operation. Note
2386  * that in order for lcb_cbflush3() to succeed, flush must already be enabled
2387  * on the bucket via the administrative interface.
2388  *
2389  * @param instance the library handle
2390  * @param cookie the cookie passed in the callback
2391  * @param cmd empty command structure. Currently there are no options for this
2392  *  command.
2393  * @return status code for scheduling.
2394  *
2395  * @attention
2396  * Because this command is built using HTTP, this is not subject to operation
2397  * pipeline calls such as lcb_sched_enter()/lcb_sched_leave()
2398  */
2399 LIBCOUCHBASE_API
2400 lcb_error_t
2401 lcb_cbflush3(lcb_t instance, const void *cookie, const lcb_CMDCBFLUSH *cmd);
2402 
2403 
2404 typedef lcb_CMDBASE lcb_CMDFLUSH;
2405 typedef lcb_RESPSERVERBASE lcb_RESPFLUSH;
2406 /**
2407  * @volatile
2408  * @deprecated
2409  */
2410 LIBCOUCHBASE_API
2411 lcb_error_t
2412 lcb_flush3(lcb_t instance, const void *cookie, const lcb_CMDFLUSH *cmd);
2413 /**@} (Group: Flush) */
2414 
2415 /**
2416  * @ingroup lcb-public-api
2417  * @defgroup lcb-noop NOOP
2418  * @brief Send NOOP command to server
2419  *
2420  * @addtogroup lcb-noop
2421  * @{
2422  */
2423 typedef lcb_CMDBASE lcb_CMDNOOP;
2424 typedef lcb_RESPSERVERBASE lcb_RESPNOOP;
2425 
2426 /**
2427  * @committed
2428  *
2429  * Send NOOP to the node
2430  *
2431  * @param instance the library handle
2432  * @param cookie the cookie passed in the callback
2433  * @param cmd empty command structure.
2434  * @return status code for scheduling.
2435  */
2436 LIBCOUCHBASE_API
2437 lcb_error_t
2438 lcb_noop3(lcb_t instance, const void *cookie, const lcb_CMDNOOP *cmd);
2439 /**@} (Group: NOOP) */
2440 
2441 /**
2442  * @ingroup lcb-public-api
2443  * @defgroup lcb-ping PING
2444  * @brief Broadcast NOOP-like commands to each service in the cluster
2445  *
2446  * @addtogroup lcb-ping
2447  * @{
2448  */
2449 
2450 /**
2451  * Ping data (Key/Value) service. Used in lcb_CMDPING#services
2452  */
2453 #define LCB_PINGSVC_F_KV 0x01
2454 
2455 /**
2456  * Ping query (N1QL) service. Used in lcb_CMDPING#services
2457  */
2458 #define LCB_PINGSVC_F_N1QL 0x02
2459 
2460 /**
2461  * Ping views (Map/Reduce) service. Used in lcb_CMDPING#services
2462  */
2463 #define LCB_PINGSVC_F_VIEWS 0x04
2464 
2465 /**
2466  * Ping full text search (FTS) service. Used in lcb_CMDPING#services
2467  */
2468 #define LCB_PINGSVC_F_FTS 0x08
2469 
2470 /**
2471  * Ping Analytics for N1QL service. Used in lcb_CMDPING#services
2472  */
2473 #define LCB_PINGSVC_F_ANALYTICS 0x10
2474 
2475 /**
2476  * Do not record any metrics or status codes from ping responses.
2477  * This might be useful to reduce overhead, when user-space
2478  * keep-alive mechanism is not interested in actual latencies,
2479  * but rather need keep sockets active. Used in lcb_CMDPING#options
2480  */
2481 #define LCB_PINGOPT_F_NOMETRICS 0x01
2482 
2483 /**
2484  * Automatically encode PING result as JSON. See njson/json fields
2485  * of #lcb_RESPPING structure. Used in lcb_CMDPING#options
2486  */
2487 #define LCB_PINGOPT_F_JSON 0x02
2488 
2489 /**
2490  * Add extra details about service status into generated JSON.
2491  * Requires LCB_PINGOPT_F_JSON to be set. Used in lcb_CMDPING#options
2492  */
2493 #define LCB_PINGOPT_F_JSONDETAILS 0x04
2494 
2495 /**
2496  * Generate indented JSON, which is better for reading. Used in lcb_CMDPING#options
2497  */
2498 #define LCB_PINGOPT_F_JSONPRETTY 0x08
2499 
2500 /**
2501  * Structure for PING requests.
2502  *
2503  * @committed
2504  */
2505 typedef struct {
2506     LCB_CMD_BASE;
2507     int services; /**< bitmap for services to ping */
2508     int options; /**< extra options, e.g. for result representation */
2509     const char *id; /**< optional, zero-terminated string to identify the report */
2510 } lcb_CMDPING;
2511 
2512 /**
2513  * Type of the service. This enumeration is used in PING responses.
2514  *
2515  * @committed
2516  */
2517 typedef enum {
2518     LCB_PINGSVC_KV = 0,
2519     LCB_PINGSVC_VIEWS,
2520     LCB_PINGSVC_N1QL,
2521     LCB_PINGSVC_FTS,
2522     LCB_PINGSVC_ANALYTICS,
2523     LCB_PINGSVC__MAX
2524 } lcb_PINGSVCTYPE;
2525 
2526 /**
2527  * Status of the service
2528  *
2529  * @committed
2530  */
2531 typedef enum {
2532     LCB_PINGSTATUS_OK = 0,
2533     LCB_PINGSTATUS_TIMEOUT,
2534     LCB_PINGSTATUS_ERROR,
2535     LCB_PINGSTATUS__MAX
2536 } lcb_PINGSTATUS;
2537 
2538 /**
2539  * Entry describing the status of the service in the cluster.
2540  * It is part of lcb_RESPING structure.
2541  *
2542  * @committed
2543  */
2544 typedef struct {
2545     lcb_PINGSVCTYPE type; /**< type of the service */
2546     /* TODO: rename to "remote" */
2547     const char *server; /**< server host:port */
2548     lcb_U64 latency; /**< latency in nanoseconds */
2549     lcb_error_t rc; /**< raw return code of the operation */
2550     const char *local; /**< server host:port */
2551     const char *id; /**< service identifier (unique in scope of lcb_t connection instance) */
2552     const char *scope; /**< optional scope name (typically equals to the bucket name) */
2553     lcb_PINGSTATUS status; /**< status of the operation */
2554 } lcb_PINGSVC;
2555 
2556 /**
2557  * Structure for PING responses.
2558  *
2559  * @committed
2560  */
2561 typedef struct {
2562     LCB_RESP_BASE
2563     LCB_RESP_SERVER_FIELDS
2564     lcb_SIZE nservices; /**< number of the nodes, replied to ping */
2565     lcb_PINGSVC *services; /**< the nodes, replied to ping, if any */
2566     lcb_SIZE njson; /**< length of JSON string (when #LCB_PINGOPT_F_JSON was specified) */
2567     const char *json; /**< pointer to JSON string */
2568 } lcb_RESPPING;
2569 
2570 /**
2571  * @brief Check connections by sending NOOP-like messages to all services.
2572  *
2573  * @committed
2574  *
2575  * When no metrics, required, it is possible to reduce memory overhead
2576  * by turning off response contents using #LCB_PINGOPT_F_NOMETRICS.
2577  *
2578  * @par Request
2579  * @code{.c}
2580  * lcb_CMDPING cmd = { 0 };
2581  * // select services to ping
2582  * cmd.services = LCB_PINGSVC_F_KV | LCB_PINGSVC_F_N1QL;
2583  * lcb_ping3(instance, fp, &cmd);
2584  * lcb_wait(instance);
2585  * @endcode
2586  *
2587  * @par Response
2588  * @code{.c}
2589  * lcb_install_callback3(instance, LCB_CALLBACK_PING, ping_callback);
2590  * void ping_callback(lcb_t, int, const lcb_RESPBASE *rb)
2591  * {
2592  *     const lcb_RESPPING *resp = (const lcb_RESPPING*)rb;
2593  *     int ii;
2594  *     for (ii = 0; ii < resp->nservices; ii++) {
2595  *         printf("service: %s, status: %d, host: %s, latency: %lu nanoseconds\n",
2596  *             resp->services[ii].type == LCB_PINGSVC_KV ? "KV" : "N1QL",
2597  *             resp->services[ii].status,
2598  *             resp->services[ii].server,
2599  *             (unsigned long)resp->services[ii].latency);
2600  *     }
2601  * }
2602  * @endcode
2603  * @param instance the library handle
2604  * @param cookie the cookie passed in the callback
2605  * @param cmd empty command structure.
2606  * @return status code for scheduling.
2607  */
2608 LIBCOUCHBASE_API
2609 lcb_error_t
2610 lcb_ping3(lcb_t instance, const void *cookie, const lcb_CMDPING *cmd);
2611 
2612 typedef struct {
2613     LCB_CMD_BASE;
2614     int options;  /**< extra options, e.g. for result representation */
2615     const char *id; /**< optional, zero-terminated string to identify the report */
2616 } lcb_CMDDIAG;
2617 
2618 typedef struct {
2619     LCB_RESP_BASE
2620     lcb_SIZE njson;   /**< length of JSON string (when #LCB_PINGOPT_F_JSON was specified) */
2621     const char *json; /**< pointer to JSON string */
2622 } lcb_RESPDIAG;
2623 
2624 /**
2625  * @brief Returns diagnostics report about network connections.
2626  *
2627  * @committed
2628  *
2629  * @par Request
2630  * @code{.c}
2631  * lcb_CMDDIAG cmd = { 0 };
2632  * lcb_diag(instance, fp, &cmd);
2633  * lcb_wait(instance);
2634  * @endcode
2635  *
2636  * @par Response
2637  * @code{.c}
2638  * lcb_install_callback3(instance, LCB_CALLBACK_DIAG, diag_callback);
2639  * void diag_callback(lcb_t, int, const lcb_RESPBASE *rb)
2640  * {
2641  *     const lcb_RESPDIAG *resp = (const lcb_RESPDIAG *)rb;
2642  *     if (resp->rc != LCB_SUCCESS) {
2643  *         fprintf(stderr, "failed: %s\n", lcb_strerror(NULL, resp->rc));
2644  *     } else {
2645  *         if (resp->njson) {
2646  *             fprintf(stderr, "\n%.*s", (int)resp->njson, resp->json);
2647  *         }
2648  *     }
2649  * }
2650  * @endcode
2651  *
2652  * @param instance the library handle
2653  * @param cookie the cookie passed in the callback
2654  * @param cmd command structure.
2655  * @return status code for scheduling.
2656  */
2657 LIBCOUCHBASE_API
2658 lcb_error_t lcb_diag(lcb_t instance, const void *cookie, const lcb_CMDDIAG *cmd);
2659 /**@} (Group: PING) */
2660 
2661 /**@ingroup lcb-public-api
2662  * @defgroup lcb-http HTTP Client
2663  * @brief Access Couchbase HTTP APIs
2664  * @details The low-level HTTP client may be used to access various HTTP-based
2665  * Couchbase APIs.
2666  *
2667  * Note that existing higher level APIs can be used for N1QL queries (see
2668  * @ref lcb-n1ql-api) and MapReduce view queries (see @ref lcb-view-api)
2669  *
2670  * @addtogroup lcb-http
2671  * @{
2672  */
2673 
2674 /**
2675  * @brief The type of HTTP request to execute
2676  */
2677 typedef enum {
2678     /**
2679      * Execute a request against the bucket. The handle must be of
2680      * @ref LCB_TYPE_BUCKET and must be connected.
2681      */
2682     LCB_HTTP_TYPE_VIEW = 0,
2683 
2684     /**
2685      * Execute a management API request. The credentials used will match
2686      * those passed during the instance creation time. Thus is the instance
2687      * type is @ref LCB_TYPE_BUCKET then only bucket-level credentials will
2688      * be used.
2689      */
2690     LCB_HTTP_TYPE_MANAGEMENT = 1,
2691 
2692     /**
2693      * Execute an arbitrary request against a host and port
2694      */
2695     LCB_HTTP_TYPE_RAW = 2,
2696 
2697     /** Execute an N1QL Query */
2698     LCB_HTTP_TYPE_N1QL = 3,
2699 
2700     /** Search a fulltext index */
2701     LCB_HTTP_TYPE_FTS = 4,
2702 
2703     /** Execute an Analytics Query */
2704     LCB_HTTP_TYPE_CBAS = 5,
2705 
2706     /**
2707      * Special pseudo-type, for ping endpoints in various services.
2708      * Behaves like RAW (the lcb_ping3() function will setup custom path),
2709      * but supports Keep-Alive
2710      */
2711     LCB_HTTP_TYPE_PING = 6,
2712 
2713     LCB_HTTP_TYPE_MAX
2714 } lcb_http_type_t;
2715 
2716 /**
2717  * @brief HTTP Request method enumeration
2718  * These just enumerate the various types of HTTP request methods supported.
2719  * Refer to the specific cluster or view API to see which method is appropriate
2720  * for your request
2721  */
2722 typedef enum {
2723     LCB_HTTP_METHOD_GET = 0,
2724     LCB_HTTP_METHOD_POST = 1,
2725     LCB_HTTP_METHOD_PUT = 2,
2726     LCB_HTTP_METHOD_DELETE = 3,
2727     LCB_HTTP_METHOD_MAX = 4
2728 } lcb_http_method_t;
2729 
2730 /**
2731  * Command flag for HTTP to indicate that the callback is to be invoked
2732  * multiple times for each new chunk of incoming data. Once the entire body
2733  * have been received, the callback will be invoked once more with the
2734  * LCB_RESP_F_FINAL flag (in lcb_RESPHTTP::rflags) and an empty content.
2735  *
2736  * To use streaming requests, this flag should be set in the
2737  * lcb_CMDHTTP::cmdflags field
2738  */
2739 #define LCB_CMDHTTP_F_STREAM (1 << 16)
2740 
2741 /**
2742  * @internal
2743  * If specified, the lcb_CMDHTTP::cas field becomes the timeout for this
2744  * specific request.
2745  */
2746 #define LCB_CMDHTTP_F_CASTMO (1 << 17)
2747 
2748 /**
2749  * @internal
2750  * Do not inject authentication header into the request.
2751  */
2752 #define LCB_CMDHTTP_F_NOUPASS (1 << 18)
2753 
2754 /**
2755  * Structure for performing an HTTP request.
2756  * Note that the key and nkey fields indicate the _path_ for the API
2757  */
2758 typedef struct {
2759     LCB_CMD_BASE;
2760     /**Type of request to issue. LCB_HTTP_TYPE_VIEW will issue a request
2761      * against a random node's view API. LCB_HTTP_TYPE_MANAGEMENT will issue
2762      * a request against a random node's administrative API, and
2763      * LCB_HTTP_TYPE_RAW will issue a request against an arbitrary host. */
2764     lcb_http_type_t type;
2765     lcb_http_method_t method; /**< HTTP Method to use */
2766 
2767     /** If the request requires a body (e.g. `PUT` or `POST`) then it will
2768      * go here. Be sure to indicate the length of the body too. */
2769     const char *body;
2770 
2771     /** Length of the body for the request */
2772     lcb_SIZE nbody;
2773 
2774     /** If non-NULL, will be assigned a handle which may be used to
2775      * subsequently cancel the request */
2776     lcb_http_request_t *reqhandle;
2777 
2778     /** For views, set this to `application/json` */
2779     const char *content_type;
2780 
2781     /** Username to authenticate with, if left empty, will use the credentials
2782      * passed to lcb_create() */
2783     const char *username;
2784 
2785     /** Password to authenticate with, if left empty, will use the credentials
2786      * passed to lcb_create() */
2787     const char *password;
2788 
2789     /** If set, this must be a string in the form of `http://host:port`. Should
2790      * only be used for raw requests. */
2791     const char *host;
2792 } lcb_CMDHTTP;
2793 
2794 /**
2795  * Structure for HTTP responses.
2796  * Note that #rc being `LCB_SUCCESS` does not always indicate that the HTTP
2797  * request itself was successful. It only indicates that the outgoing request
2798  * was submitted to the server and the client received a well-formed HTTP
2799  * response. Check the #hstatus field to see the actual HTTP-level status
2800  * code received.
2801  */
2802 typedef struct {
2803     LCB_RESP_BASE
2804     /**HTTP status code. The value is only valid if #rc is ::LCB_SUCCESS
2805      * (if #rc is not LCB_SUCCESS then this field may be 0 as the response may
2806      * have not been read/sent) */
2807     short htstatus;
2808 
2809     /**List of key-value headers. This field itself may be `NULL`. The list
2810      * is terminated by a `NULL` pointer to indicate no more headers. */
2811     const char * const * headers;
2812 
2813     /**If @ref LCB_CMDHTTP_F_STREAM is true, contains the current chunk
2814      * of response content. Otherwise, contains the entire response body.*/
2815     const void *body;
2816     /** Length of buffer in #body */
2817     lcb_SIZE nbody;
2818     /**@internal*/
2819     lcb_http_request_t _htreq;
2820 } lcb_RESPHTTP;
2821 
2822 /**
2823  * @committed
2824  * Issue an HTTP API request.
2825  * @param instance the library handle
2826  * @param cookie cookie to be associated with the request
2827  * @param cmd the command
2828  * @return LCB_SUCCESS if the request was scheduled successfully.
2829  *
2830  *
2831  * @par Simple Response
2832  * @code{.c}
2833  * void http_callback(lcb_t, int, const lcb_RESPBASE *rb)
2834  * {
2835  *     const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)rb;
2836  *     if (resp->rc != LCB_SUCCESS) {
2837  *         printf("I/O Error for HTTP: %s\n", lcb_strerror(NULL, resp->rc));
2838  *         return;
2839  *     }
2840  *     printf("Got HTTP Status: %d\n", resp->htstatus);
2841  *     printf("Got paylod: %.*s\n", (int)resp->nbody, resp->body);
2842  *     const char **hdrp = resp->headers;
2843  *     while (*hdrp != NULL) {
2844  *         printf("%s: %s\n", hdrp[0], hdrp[1]);
2845  *         hdrp += 2;
2846  *     }
2847  * }
2848  * @endcode
2849  *
2850  * @par Streaming Response
2851  * If the @ref LCB_CMDHTTP_F_STREAM flag is set in lcb_CMDHTTP::cmdflags then the
2852  * response callback is invoked multiple times as data arrives off the socket.
2853  * @code{.c}
2854  * void http_strm_callback(lcb_t, int, const lcb_RESPBASE *rb)
2855  * {
2856  *     const lcb_RESPHTTP *resp = (const lcb_RESPHTTP *)resp;
2857  *     if (resp->rflags & LCB_RESP_F_FINAL) {
2858  *         if (resp->rc != LCB_SUCCESS) {
2859  *             // ....
2860  *         }
2861  *         const char **hdrp = resp->headers;
2862  *         // ...
2863  *     } else {
2864  *         handle_body(resp->body, resp->nbody);
2865  *     }
2866  * }
2867  * @endcode
2868  *
2869  * @par Connection Reuse
2870  * The library will attempt to reuse connections for frequently contacted hosts.
2871  * By default the library will keep one idle connection to each host for a maximum
2872  * of 10 seconds. The number of open idle HTTP connections can be controlled with
2873  * @ref LCB_CNTL_HTTP_POOLSIZE.
2874  *
2875  */
2876 LIBCOUCHBASE_API
2877 lcb_error_t
2878 lcb_http3(lcb_t instance, const void *cookie, const lcb_CMDHTTP *cmd);
2879 
2880 /**
2881  * @brief Cancel ongoing HTTP request
2882  *
2883  * This API will stop the current request. Any pending callbacks will not be
2884  * invoked any any pending data will not be delivered. Useful for a long running
2885  * request which is no longer needed
2886  *
2887  * @param instance The handle to lcb
2888  * @param request The request handle
2889  *
2890  * @committed
2891  *
2892  * @par Example
2893  * @code{.c}
2894  * lcb_CMDHTTP htcmd = { 0 };
2895  * populate_htcmd(&htcmd); // dummy function
2896  * lcb_http_request_t reqhandle;
2897  * htcmd.reqhandle = &reqhandle;
2898  * lcb_http3(instance, cookie, &htcmd);
2899  * do_stuff();
2900  * lcb_cancel_http_request(instance, reqhandle);
2901  * @endcode
2902  */
2903 LIBCOUCHBASE_API
2904 void
2905 lcb_cancel_http_request(lcb_t instance, lcb_http_request_t request);
2906 /**@} (Group: HTTP) */
2907 
2908 /**
2909  * @ingroup lcb-public-api
2910  * @defgroup lcb-cookie User Cookies
2911  * @brief Associate user-defined data with operations
2912  * @details
2913  *
2914  * User-defined pointers may be passed to all operations in the form of a
2915  * `cookie` parameter. This cookie parameter allows any kind of application
2916  * context to be accessible via the callback (in lcb_RESPBASE::cookie).
2917  *
2918  * The library will not inspect or manage the address or contents of the
2919  * cookie; it may live on the stack (especially if using the library
2920  * synchronously), on the heap, or may be NULL altogether.
2921  *
2922  * In addition to per-operation cookies, the library allows the instance itself
2923  * (i.e. the `lcb_t` object) to contain its own cookie. This is helpful when
2924  * there is a wrapper object which needs to be accessed from within the callback
2925  *
2926  * @addtogroup lcb-cookie
2927  * @{
2928  */
2929 
2930 /**
2931  * Associate a cookie with an instance of lcb. The _cookie_ is a user defined
2932  * pointer which will remain attached to the specified `lcb_t` for its duration.
2933  * This is the way to associate user data with the `lcb_t`.
2934  *
2935  * @param instance the instance to associate the cookie to
2936  * @param cookie the cookie to associate with this instance.
2937  *
2938  * @attention
2939  * There is no destructor for the specified `cookie` stored with the instance;
2940  * thus you must ensure to manually free resources to the pointer (if it was
2941  * dynamically allocated) when it is no longer required.
2942  * @committed
2943  *
2944  * @code{.c}
2945  * typedef struct {
2946  *   const char *status;
2947  *   // ....
2948  * } instance_info;
2949  *
2950  * static void bootstrap_callback(lcb_t instance, lcb_error_t err) {
2951  *   instance_info *info = (instance_info *)lcb_get_cookie(instance);
2952  *   if (err == LCB_SUCCESS) {
2953  *     info->status = "Connected";
2954  *   } else {
2955  *     info->status = "Error";
2956  *   }
2957  * }
2958  *
2959  * static void do_create(void) {
2960  *   instance_info *info = calloc(1, sizeof(*info));
2961  *   // info->status is currently NULL
2962  *   // .. create the instance here
2963  *   lcb_set_cookie(instance, info);
2964  *   lcb_set_bootstrap_callback(instance, bootstrap_callback);
2965  *   lcb_connect(instance);
2966  *   lcb_wait(instance);
2967  *   printf("Status of instance is %s\n", info->status);
2968  * }
2969  * @endcode
2970  */
2971 LIBCOUCHBASE_API
2972 void lcb_set_cookie(lcb_t instance, const void *cookie);
2973 
2974 /**
2975  * Retrieve the cookie associated with this instance
2976  * @param instance the instance of lcb
2977  * @return The cookie associated with this instance or NULL
2978  * @see lcb_set_cookie()
2979  * @committed
2980  */
2981 LIBCOUCHBASE_API
2982 const void *lcb_get_cookie(lcb_t instance);
2983 /**@} (Group: Cookies) */
2984 
2985 /**
2986  * @defgroup lcb-wait Waiting
2987  * @brief Functions for synchronous I/O execution
2988  * @details The lcb_wait() family of functions allow to control when the
2989  * library sends the operations to the cluster and waits for their execution.
2990  *
2991  * It is also possible to use non-blocking I/O with the library
2992  *
2993  * @addtogroup lcb-wait
2994  * @{
2995  */
2996 
2997 /**
2998  * @brief Wait for the execution of all batched requests
2999  *
3000  * A batched request is any request which requires network I/O.
3001  * This includes most of the APIs. You should _not_ use this API if you are
3002  * integrating with an asynchronous event loop (i.e. one where your application
3003  * code is invoked asynchronously via event loops).
3004  *
3005  * This function will block the calling thread until either
3006  *
3007  * * All operations have been completed
3008  * * lcb_breakout() is explicitly called
3009  *
3010  * @param instance the instance containing the requests
3011  * @return whether the wait operation failed, or LCB_SUCCESS
3012  * @committed
3013  */
3014 LIBCOUCHBASE_API
3015 lcb_error_t lcb_wait(lcb_t instance);
3016 
3017 /**
3018  * @volatile
3019  * This function will cause a single "tick" in the underlying event loop,
3020  * causing operations whose I/O can be executed immediately to be sent to
3021  * the server.
3022  *
3023  * Like lcb_wait(), callbacks for operations may be delivered here, however
3024  * some operations may be left incomplete if their I/O could not be processed
3025  * immediately. This function is intended as an optimization for large batches
3026  * of operations - so that some I/O can be completed during the batching process
3027  * itself, and only the remainder of those operations (which would have blocked)
3028  * will be completed with lcb_wait() (which should be invoked after the batch).
3029  *
3030  * This function is mainly useful if there is a significant delay in time
3031  * between each scheduling function, in which I/O may be completed during these
3032  * gaps (thereby emptying the socket's kernel write buffer, and allowing for
3033  * new operations to be added after the interval). Calling this function for
3034  * batches where all data is available up-front may actually make things slower.
3035  *
3036  * @warning
3037  * You must call lcb_wait() at least one after any batch of operations to ensure
3038  * they have been completed. This function is provided as an optimization only.
3039  *
3040  * @return LCB_CLIENT_FEATURE_UNAVAILABLE if the event loop does not support
3041  * the "tick" mode.
3042  */
3043 LIBCOUCHBASE_API
3044 lcb_error_t lcb_tick_nowait(lcb_t instance);
3045 
3046 /**@brief Flags for lcb_wait3()*/
3047 typedef enum {
3048     /**Behave like the old lcb_wait()*/
3049     LCB_WAIT_DEFAULT = 0x00,
3050 
3051     /**Do not check pending operations before running the event loop. By default
3052      * lcb_wait() will traverse the server list to check if any operations are
3053      * pending, and if nothing is pending the function will return without
3054      * running the event loop. This is usually not necessary for applications
3055      * which already _only_ call lcb_wait() when they know they have scheduled
3056      * at least one command.
3057      */
3058     LCB_WAIT_NOCHECK = 0x01
3059 } lcb_WAITFLAGS;
3060 
3061 /**
3062  * @committed
3063  * @brief Wait for completion of scheduled operations.
3064  * @param instance the instance
3065  * @param flags flags to modify the behavior of lcb_wait(). Pass 0 to obtain
3066  * behavior identical to lcb_wait().
3067  */
3068 LIBCOUCHBASE_API
3069 void lcb_wait3(lcb_t instance, lcb_WAITFLAGS flags);
3070 
3071 /**
3072  * @brief Forcefully break from the event loop.
3073  *
3074  * You may call this function from within any callback to signal to the library
3075  * that it return control to the function calling lcb_wait() as soon as possible.
3076  * Note that if there are pending functions which have not been processed, you
3077  * are responsible for calling lcb_wait() a second time.
3078  *
3079  * @param instance the instance to run the event loop for.
3080  * @committed
3081  */
3082 LIBCOUCHBASE_API
3083 void lcb_breakout(lcb_t instance);
3084 
3085 /**
3086  * @brief Check if instance is blocked in the event loop
3087  * @param instance the instance to run the event loop for.
3088  * @return non-zero if nobody is waiting for IO interaction
3089  * @uncommitted
3090  */
3091 LIBCOUCHBASE_API
3092 int lcb_is_waiting(lcb_t instance);
3093 /**@} (Group: Wait) */
3094 
3095 /**
3096  * @uncommitted
3097  *
3098  * @brief Force the library to refetch the cluster configuration
3099  *
3100  * The library by default employs various heuristics to determine if a new
3101  * configuration is needed from the cluster. However there are some situations
3102  * in which an application may wish to force a refresh of the configuration:
3103  *
3104  * * If a specific node has been failed
3105  *   over and the library has received a configuration in which there is no
3106  *   master node for a given key, the library will immediately return the error
3107  *   `LCB_NO_MATCHING_SERVER` for the given item and will not request a new
3108  *   configuration. In this state, the client will not perform any network I/O
3109  *   until a request has been made to it using a key that is mapped to a known
3110  *   active node.
3111  *
3112  * * The library's heuristics may have failed to detect an error warranting
3113  *   a configuration change, but the application either through its own
3114  *   heuristics, or through an out-of-band channel knows that the configuration
3115  *   has changed.
3116  *
3117  *
3118  * This function is provided as an aid to assist in such situations
3119  *
3120  * If you wish for your application to block until a new configuration is
3121  * received, you _must_ call lcb_wait3() with the LCB_WAIT_NO_CHECK flag as
3122  * this function call is not bound to a specific operation. Additionally there
3123  * is no status notification as to whether this operation succeeded or failed
3124  * (the configuration callback via lcb_set_configuration_callback() may
3125  * provide hints as to whether a configuration was received or not, but by no
3126  * means should be considered to be part of this function's control flow).
3127  *
3128  * In general the use pattern of this function is like so:
3129  *
3130  * @code{.c}
3131  * unsigned retries = 5;
3132  * lcb_error_t err;
3133  * do {
3134  *   retries--;
3135  *   err = lcb_get(instance, cookie, ncmds, cmds);
3136  *   if (err == LCB_NO_MATCHING_SERVER) {
3137  *     lcb_refresh_config(instance);
3138  *     usleep(100000);
3139  *     lcb_wait3(instance, LCB_WAIT_NO_CHECK);
3140  *   } else {
3141  *     break;
3142  *   }
3143  * } while (retries);
3144  * if (err == LCB_SUCCESS) {
3145  *   lcb_wait3(instance, 0); // equivalent to lcb_wait(instance);
3146  * } else {
3147  *   printf("Tried multiple times to fetch the key, but its node is down\n");
3148  * }
3149  * @endcode
3150  */
3151 LIBCOUCHBASE_API
3152 void
3153 lcb_refresh_config(lcb_t instance);
3154 
3155 /**
3156  * @ingroup lcb-public-api
3157  * @defgroup lcb-sched Advanced Scheduling
3158  * @brief Additional functions for scheduling operations
3159  *
3160  * @details
3161  *
3162  * An application may spool multiple operations into the library with the
3163  * option of unspooling previously-spooled operations in case one of
3164  * the operations cannot be spooled. These semantics exist primarily to
3165  * support "all-or-nothing" scheduling found in the V2 API as well as in
3166  * some other wrapping SDKs.
3167  *
3168  * From version 2.4.0 to version 2.5.5, use of the explicit scheduling
3169  * API was mandatory to schedule operations. This API is optional since 2.5.6.
3170  *
3171  * The following operation APIs are low level entry points which create a
3172  * single operation. To use these operation APIs you should call the
3173  * lcb_sched_enter() which creates a virtual scope in which to create operations.
3174  *
3175  * For each of these operation APIs, the actual API call will insert the
3176  * created packet into a "Scheduling Queue" (this is done through
3177  * mcreq_sched_add() which is in mcreq.h). You may add as many items to this
3178  * scheduling queue as you would like.
3179  *
3180  * Note that an operation is only added to the queue if it was able to be
3181  * scheduled properly. If a scheduling failure occurred (for example, if a
3182  * configuration is missing, the command had invalid input, or memory allocation
3183  * failed) then the command will not be placed into the queue.
3184  *
3185  * Once all operations have been scheduled you can call
3186  * lcb_sched_leave() which will place all commands scheduled into the I/O
3187  * queue.
3188  *
3189  * If you wish to _discard_ all scheduled operations (for example, if one of
3190  * them errored, and your application cannot handle partial scheduling failures)
3191  * then you may call lcb_sched_fail() which will release all the resources
3192  * of the packets placed into the temporary queue.
3193  *
3194  * @par Behavior from version 2.5.6
3195  *
3196  * Starting from version 2.5.6, use of this API is optional. Scheduling functions
3197  * will now check if an empty call to lcb_sched_enter() is present. If no call
3198  * to lcb_sched_enter() is found then the library will implicitly call
3199  * lcb_sched_leave().
3200  *
3201  * @addtogroup lcb-sched
3202  * @{
3203  */
3204 
3205 /**
3206  * @brief Enter a scheduling context.
3207  *
3208  * @uncommitted
3209  *
3210  * A scheduling context is an ephemeral list of
3211  * commands issued to various servers. Operations (like lcb_get3(), lcb_store3())
3212  * place packets into the current context.
3213  *
3214  * The context mechanism allows you to efficiently pipeline and schedule multiple
3215  * operations of different types and quantities. The network is not touched
3216  * and nothing is scheduled until the context is exited.
3217  *
3218  * @param instance the instance
3219  *
3220  * @code{.c}
3221  * lcb_sched_enter(instance);
3222  * lcb_get3(...);
3223  * lcb_store3(...);
3224  * lcb_counter3(...);
3225  * lcb_sched_leave(instance);
3226  * lcb_wait3(instance, LCB_WAIT_NOCHECK);
3227  * @endcode
3228  */
3229 LIBCOUCHBASE_API
3230 void lcb_sched_enter(lcb_t instance);
3231 
3232 /**
3233  * @uncommitted
3234  *
3235  * @brief Leave the current scheduling context, scheduling the commands within the
3236  * context to be flushed to the network.
3237  *
3238  * @details This will initiate a network-level flush (depending on the I/O system)
3239  * to the network. For completion-based I/O systems this typically means
3240  * allocating a temporary write context to contain the buffer. If using a
3241  * completion-based I/O module (for example, Windows or libuv) then it is
3242  * recommended to limit the number of calls to one per loop iteration. If
3243  * limiting the number of calls to this function is not possible (for example,
3244  * if the legacy API is being used, or you wish to use implicit scheduling) then
3245  * the flushing may be decoupled from this function - see the documentation for
3246  * lcb_sched_flush().
3247  *
3248  * @param instance the instance
3249  */
3250 LIBCOUCHBASE_API
3251 void lcb_sched_leave(lcb_t instance);
3252 
3253 
3254 /**
3255  * @uncommitted
3256  * @brief Fail all commands in the current scheduling context.
3257  *
3258  * The commands placed within the current
3259  * scheduling context are released and are never flushed to the network.
3260  * @param instance
3261  *
3262  * @warning
3263  * This function only affects commands which have a direct correspondence
3264  * to memcached packets. Currently these are commands scheduled by:
3265  *
3266  * * lcb_get3()
3267  * * lcb_rget3()
3268  * * lcb_unlock3()
3269  * * lcb_touch3()
3270  * * lcb_store3()
3271  * * lcb_counter3()
3272  * * lcb_remove3()
3273  * * lcb_stats3()
3274  * * lcb_observe3_ctxnew()
3275  * * lcb_observe_seqno3()
3276  *
3277  * Other commands are _compound_ commands and thus should be in their own
3278  * scheduling context.
3279  */
3280 LIBCOUCHBASE_API
3281 void lcb_sched_fail(lcb_t instance);
3282 
3283 /**
3284  * @committed
3285  * @brief Request commands to be flushed to the network
3286  *
3287  * By default, the library will implicitly request a flush to the network upon
3288  * every call to lcb_sched_leave().
3289  *
3290  * [ Note, this does not mean the items are flushed
3291  * and I/O is performed, but it means the relevant event loop watchers are
3292  * activated to perform the operations on the next iteration ]. If
3293  * @ref LCB_CNTL_SCHED_IMPLICIT_FLUSH
3294  * is disabled then this behavior is disabled and the
3295  * application must explicitly call lcb_sched_flush(). This may be considered
3296  * more performant in the cases where multiple discreet operations are scheduled
3297  * in an lcb_sched_enter()/lcb_sched_leave() pair. With implicit flush enabled,
3298  * each call to lcb_sched_leave() will possibly invoke system repeatedly.
3299  */
3300 LIBCOUCHBASE_API
3301 void lcb_sched_flush(lcb_t instance);
3302 
3303 /**@} (Group: Adanced Scheduling) */
3304 
3305 /**@ingroup lcb-public-api
3306  * @defgroup lcb-destroy Destroying
3307  * @brief Library destruction routines
3308  * @addtogroup lcb-destroy
3309  * @{
3310  */
3311 /**
3312  * Destroy (and release all allocated resources) an instance of lcb.
3313  * Using instance after calling destroy will most likely cause your
3314  * application to crash.
3315  *
3316  * Note that any pending operations will not have their callbacks invoked.
3317  *
3318  * @param instance the instance to destroy.
3319  * @committed
3320  */
3321 LIBCOUCHBASE_API
3322 void lcb_destroy(lcb_t instance);
3323 
3324 /**
3325  * @brief Callback received when instance is about to be destroyed
3326  * @param cookie cookie passed to lcb_destroy_async()
3327  */
3328 typedef void (*lcb_destroy_callback)(const void *cookie);
3329 
3330 /**
3331  * @brief Set the callback to be invoked when the instance is destroyed
3332  * asynchronously.
3333  * @return the previous callback.
3334  */
3335 LIBCOUCHBASE_API
3336 lcb_destroy_callback
3337 lcb_set_destroy_callback(lcb_t, lcb_destroy_callback);
3338 /**
3339  * @brief Asynchronously schedule the destruction of an instance.
3340  *
3341  * This function provides a safe way for asynchronous environments to destroy
3342  * the lcb_t handle without worrying about reentrancy issues.
3343  *
3344  * @param instance
3345  * @param arg a pointer passed to the callback.
3346  *
3347  * While the callback and cookie are optional, they are very much recommended
3348  * for testing scenarios where you wish to ensure that all resources allocated
3349  * by the instance have been closed. Specifically when the callback is invoked,
3350  * all timers (save for the one actually triggering the destruction) and sockets
3351  * will have been closed.
3352  *
3353  * As with lcb_destroy() you may call this function only once. You may not
3354  * call this function together with lcb_destroy as the two are mutually
3355  * exclusive.
3356  *
3357  * If for whatever reason this function is being called in a synchronous
3358  * flow, lcb_wait() must be invoked in order for the destruction to take effect
3359  *
3360  * @see lcb_set_destroy_callback
3361  *
3362  * @committed
3363  */
3364 LIBCOUCHBASE_API
3365 void lcb_destroy_async(lcb_t instance, const void *arg);
3366 /**@} (Group: Destroy) */
3367 
3368 /**@}*/
3369 
3370 /** @internal */
3371 #define LCB_DATATYPE_JSON 0x01
3372 
3373 /** @internal */
3374 typedef enum { LCB_VALUE_RAW = 0x00, LCB_VALUE_F_JSON = 0x01, LCB_VALUE_F_SNAPPYCOMP = 0x02 } lcb_VALUEFLAGS;
3375 
3376 
3377 /**
3378  * @ingroup lcb-public-api
3379  * @defgroup lcb-cluster-status Cluster Information
3380  * @brief These functions return status information about the handle, the current
3381  * connection, and the number of nodes found within the cluster.
3382  *
3383  * @see lcb_cntl() for more functions to retrieve status info
3384  *
3385  * @addtogroup lcb-cluster-status
3386  * @{
3387  */
3388 
3389 /**@brief
3390  * Type of node to retrieve for the lcb_get_node() function
3391  */
3392 typedef enum {
3393     /** Get an HTTP configuration (Rest API) node */
3394     LCB_NODE_HTCONFIG = 0x01,
3395     /** Get a data (memcached) node */
3396     LCB_NODE_DATA = 0x02,
3397     /** Get a view (CAPI) node */
3398     LCB_NODE_VIEWS = 0x04,
3399     /** Only return a node which is connected, or a node which is known to be up */
3400     LCB_NODE_CONNECTED = 0x08,
3401 
3402     /** Specifying this flag adds additional semantics which instruct the library
3403      * to search additional resources to return a host, and finally,
3404      * if no host can be found, return the string
3405      * constant @ref LCB_GETNODE_UNAVAILABLE. */
3406     LCB_NODE_NEVERNULL = 0x10,
3407 
3408     /** Equivalent to `LCB_NODE_HTCONFIG|LCB_NODE_CONNECTED` */
3409     LCB_NODE_HTCONFIG_CONNECTED = 0x09,
3410 
3411     /**Equivalent to `LCB_NODE_HTCONFIG|LCB_NODE_NEVERNULL`.
3412      * When this is passed, some additional attempts may be made by the library
3413      * to return any kind of host, including searching the initial list of hosts
3414      * passed to the lcb_create() function. */
3415     LCB_NODE_HTCONFIG_ANY = 0x11
3416 } lcb_GETNODETYPE;
3417 
3418 /** String constant returned by lcb_get_node() when the @ref LCB_NODE_NEVERNULL
3419  * flag is specified, and no node can be returned */
3420 #define LCB_GETNODE_UNAVAILABLE "invalid_host:0"
3421 
3422 /**
3423  * @brief Return a string of `host:port` for a node of the given type.
3424  *
3425  * @param instance the instance from which to retrieve the node
3426  * @param type the type of node to return
3427  * @param index the node number if index is out of bounds it will be wrapped
3428  * around, thus there is never an invalid value for this parameter
3429  *
3430  * @return a string in the form of `host:port`. If LCB_NODE_NEVERNULL was specified
3431  * as an option in `type` then the string constant LCB_GETNODE_UNAVAILABLE is
3432  * returned. Otherwise `NULL` is returned if the type is unrecognized or the
3433  * LCB_NODE_CONNECTED option was specified and no connected node could be found
3434  * or a memory allocation failed.
3435  *
3436  * @note The index parameter is _ignored_ if `type` is
3437  * LCB_NODE_HTCONFIG|LCB_NODE_CONNECTED as there will always be only a single
3438  * HTTP bootstrap node.
3439  *
3440  * @code{.c}
3441  * const char *viewnode = lcb_get_node(instance, LCB_NODE_VIEWS, 0);
3442  * // Get the connected REST endpoint:
3443  * const char *restnode = lcb_get_node(instance, LCB_NODE_HTCONFIG|LCB_NODE_CONNECTED, 0);
3444  * if (!restnode) {
3445  *   printf("Instance not connected via HTTP!\n");
3446  * }
3447  * @endcode
3448  *
3449  * Iterate over all the data nodes:
3450  * @code{.c}
3451  * unsigned ii;
3452  * for (ii = 0; ii < lcb_get_num_servers(instance); ii++) {
3453  *   const char *kvnode = lcb_get_node(instance, LCB_NODE_DATA, ii);
3454  *   if (kvnode) {
3455  *     printf("KV node %s exists at index %u\n", kvnode, ii);
3456  *   } else {
3457  *     printf("No node for index %u\n", ii);
3458  *   }
3459  * }
3460  * @endcode
3461  *
3462  * @committed
3463  */
3464 LIBCOUCHBASE_API
3465 const char *
3466 lcb_get_node(lcb_t instance, lcb_GETNODETYPE type, unsigned index);
3467 
3468 /**
3469  * @committed
3470  *
3471  * @brief Get the target server for a given key.
3472  *
3473  * This is a convenience function wrapping around the vBucket API which allows
3474  * you to retrieve the target node (the node which will be contacted) when
3475  * performing KV operations involving the key.
3476  *
3477  * @param instance the instance
3478  * @param key the key to use
3479  * @param nkey the length of the key
3480  * @return a string containing the hostname, or NULL on error.
3481  *
3482  * Since this is a convenience function, error details are not contained here
3483  * in favor of brevity. Use the full vBucket API for more powerful functions.
3484  */
3485 LIBCOUCHBASE_API
3486 const char *
3487 lcb_get_keynode(lcb_t instance, const void *key, size_t nkey);
3488 
3489 /**
3490  * @brief Get the number of the replicas in the cluster
3491  *
3492  * @param instance The handle to lcb
3493  * @return -1 if the cluster wasn't configured yet, and number of replicas
3494  * otherwise. This may be `0` if there are no replicas.
3495  * @committed
3496  */
3497 LIBCOUCHBASE_API
3498 lcb_S32 lcb_get_num_replicas(lcb_t instance);
3499 
3500 /**
3501  * @brief Get the number of the nodes in the cluster
3502  * @param instance The handle to lcb
3503  * @return -1 if the cluster wasn't configured yet, and number of nodes otherwise.
3504  * @committed
3505  */
3506 LIBCOUCHBASE_API
3507 lcb_S32 lcb_get_num_nodes(lcb_t instance);
3508 
3509 
3510 /**
3511  * @brief Get a list of nodes in the cluster
3512  *
3513  * @return a NULL-terminated list of 0-terminated strings consisting of
3514  * node hostnames:admin_ports for the entire cluster.
3515  * The storage duration of this list is only valid until the
3516  * next call to a libcouchbase function and/or when returning control to
3517  * libcouchbase' event loop.
3518  *
3519  * @code{.c}
3520  * const char * const * curp = lcb_get_server_list(instance);
3521  * for (; *curp; curp++) {
3522  *   printf("Have node %s\n", *curp);
3523  * }
3524  * @endcode
3525  * @committed
3526  */
3527 LIBCOUCHBASE_API
3528 const char *const *lcb_get_server_list(lcb_t instance);
3529 
3530 /**
3531  * @volatile
3532  * @brief Write a textual dump to a file.
3533  *
3534  * This function will inspect the various internal structures of the current
3535  * client handle (indicated by `instance`) and write the state information
3536  * to the file indicated by `fp`.
3537  * @param instance the handle to dump
3538  * @param fp the file to which the dump should be written
3539  * @param flags a set of modifiers (of @ref lcb_DUMPFLAGS) indicating what
3540  * information to dump. Note that a standard set of information is always
3541  * dumped, but by default more verbose information is hidden, and may be
3542  * enabled with these flags.
3543  */
3544 LIBCOUCHBASE_API
3545 void
3546 lcb_dump(lcb_t instance, FILE *fp, lcb_U32 flags);
3547 /**@} (Group: Cluster Info) */
3548 
3549 /**
3550  * @ingroup lcb-public-api
3551  * @defgroup lcb-cntl Settings
3552  * @brief Get/Set Library Options
3553  *
3554  * @details
3555  *
3556  * The lcb_cntl() function and its various helpers are the means by which to
3557  * modify settings within the library
3558  *
3559  * @addtogroup lcb-cntl
3560  * @see <cntl.h>
3561  * @{
3562  */
3563 
3564 /**
3565  * This function exposes an ioctl/fcntl-like interface to read and write
3566  * various configuration properties to and from an lcb_t handle.
3567  *
3568  * @param instance The instance to modify
3569  *
3570  * @param mode One of LCB_CNTL_GET (to retrieve a setting) or LCB_CNTL_SET
3571  *      (to modify a setting). Note that not all configuration properties
3572  *      support SET.
3573  *
3574  * @param cmd The specific command/property to modify. This is one of the
3575  *      LCB_CNTL_* constants defined in this file. Note that it is safe
3576  *      (and even recommanded) to use the raw numeric value (i.e.
3577  *      to be backwards and forwards compatible with libcouchbase
3578  *      versions), as they are not subject to change.
3579  *
3580  *      Using the actual value may be useful in ensuring your application
3581  *      will still compile with an older libcouchbase version (though
3582  *      you may get a runtime error (see return) if the command is not
3583  *      supported
3584  *
3585  * @param arg The argument passed to the configuration handler.
3586  *      The actual type of this pointer is dependent on the
3587  *      command in question.  Typically for GET operations, the
3588  *      value of 'arg' is set to the current configuration value;
3589  *      and for SET operations, the current configuration is
3590  *      updated with the contents of *arg.
3591  *
3592  * @return ::LCB_NOT_SUPPORTED if the code is unrecognized
3593  * @return ::LCB_EINVAL if there was a problem with the argument
3594  *         (typically for LCB_CNTL_SET) other error codes depending on the command.
3595  *
3596  * The following error codes are returned if the ::LCB_CNTL_DETAILED_ERRCODES
3597  * are enabled.
3598  *
3599  * @return ::LCB_ECTL_UNKNOWN if the code is unrecognized
3600  * @return ::LCB_ECTL_UNSUPPMODE An invalid _mode_ was passed
3601  * @return ::LCB_ECTL_BADARG if the value was invalid
3602  *
3603  * @committed
3604  *
3605  * @see lcb_cntl_setu32()
3606  * @see lcb_cntl_string()
3607  */
3608 LIBCOUCHBASE_API
3609 lcb_error_t lcb_cntl(lcb_t instance, int mode, int cmd, void *arg);
3610 
3611 /**
3612  * Alternatively one may change configuration settings by passing a string key
3613  * and value. This may be used to provide a simple interface from a command
3614  * line or higher level language to allow the setting of specific key-value
3615  * pairs.
3616  *
3617  * The format for the value is dependent on the option passed, the following
3618  * value types exist:
3619  *
3620  * - **Timeval**. A _timeval_ value can either be specified as fractional
3621  *   seconds (`"1.5"` for 1.5 seconds), or in microseconds (`"1500000"`). In
3622  *   releases prior to libcouchbase 2.8, this was called _timeout_.
3623  * - **Number**. This is any valid numerical value. This may be signed or
3624  *   unsigned depending on the setting.
3625  * - **Boolean**. This specifies a boolean. A true value is either a positive
3626  *   numeric value (i.e. `"1"`) or the string `"true"`. A false value
3627  *   is a zero (i.e. `"0"`) or the string `"false"`.
3628  * - **Float**. This is like a _Number_, but also allows fractional specification,
3629  *   e.g. `"2.4"`.
3630  * - **String**. Arbitrary string as `char *`, e.g. for client identification
3631  *   string.
3632  * - **Path**. File path.
3633  * - **FILE*, Path**. Set file stream pointer (lcb_cntl() style) or file path
3634  *   (lcb_cntl_string() style).
3635  *
3636  * | Code                                    | Name                      | Type              |
3637  * |-----------------------------------------|---------------------------|-------------------|
3638  * |@ref LCB_CNTL_OP_TIMEOUT                 | `"operation_timeout"`     | Timeval           |
3639  * |@ref LCB_CNTL_VIEW_TIMEOUT               | `"view_timeout"`          | Timeval           |
3640  * |@ref LCB_CNTL_N1QL_TIMEOUT               | `"n1ql_timeout"`          | Timeval           |
3641  * |@ref LCB_CNTL_HTTP_TIMEOUT               | `"http_timeout"`          | Timeval           |
3642  * |@ref LCB_CNTL_CONFIG_POLL_INTERVAL       | `"config_poll_interval"`  | Timeval           |
3643  * |@ref LCB_CNTL_CONFERRTHRESH              | `"error_thresh_count"`    | Number (Positive) |
3644  * |@ref LCB_CNTL_CONFIGURATION_TIMEOUT      | `"config_total_timeout"`  | Timeval           |
3645  * |@ref LCB_CNTL_CONFIG_NODE_TIMEOUT        | `"config_node_timeout"`   | Timeval           |
3646  * |@ref LCB_CNTL_CONFDELAY_THRESH           | `"error_thresh_delay"`    | Timeval           |
3647  * |@ref LCB_CNTL_DURABILITY_TIMEOUT         | `"durability_timeout"`    | Timeval           |
3648  * |@ref LCB_CNTL_DURABILITY_INTERVAL        | `"durability_interval"`   | Timeval           |
3649  * |@ref LCB_CNTL_RANDOMIZE_BOOTSTRAP_HOSTS  | `"randomize_nodes"`       | Boolean           |
3650  * |@ref LCB_CNTL_CONFIGCACHE                | `"config_cache"`          | Path              |
3651  * |@ref LCB_CNTL_DETAILED_ERRCODES          | `"detailed_errcodes"`     | Boolean           |
3652  * |@ref LCB_CNTL_HTCONFIG_URLTYPE           | `"http_urlmode"`          | Number (enum #lcb_HTCONFIG_URLTYPE) |
3653  * |@ref LCB_CNTL_RETRY_BACKOFF              | `"retry_backoff"`         | Float             |
3654  * |@ref LCB_CNTL_RETRY_INTERVAL             | `"retry_interval"`        | Timeval           |
3655  * |@ref LCB_CNTL_HTTP_POOLSIZE              | `"http_poolsize"`         | Number            |
3656  * |@ref LCB_CNTL_VBGUESS_PERSIST            | `"vbguess_persist"`       | Boolean           |
3657  * |@ref LCB_CNTL_CONLOGGER_LEVEL            | `"console_log_level"`     | Number (enum #lcb_log_severity_t) |
3658  * |@ref LCB_CNTL_FETCH_MUTATION_TOKENS      | `"fetch_mutation_tokens"` | Boolean           |
3659  * |@ref LCB_CNTL_DURABILITY_MUTATION_TOKENS | `"dur_mutation_tokens"`   | Boolean           |
3660  * |@ref LCB_CNTL_TCP_NODELAY                | `"tcp_nodelay"`           | Boolean           |
3661  * |@ref LCB_CNTL_CONLOGGER_FP               | `"console_log_file"`      | FILE*, Path       |
3662  * |@ref LCB_CNTL_CLIENT_STRING              | `"client_string"`         | String            |
3663  * |@ref LCB_CNTL_TCP_KEEPALIVE              | `"tcp_keepalive"`         | Boolean           |
3664  * |@ref LCB_CNTL_CONFIG_POLL_INTERVAL       | `"config_poll_interval"`  | Timeval           |
3665  * |@ref LCB_CNTL_IP6POLICY                  | `"ipv6"`                  | String ("disabled", "only", "allow") |
3666  *
3667  * @committed - Note, the actual API call is considered committed and will
3668  * not disappear, however the existence of the various string settings are
3669  * dependendent on the actual settings they map to. It is recommended that
3670  * applications use the numerical lcb_cntl() as the string names are
3671  * subject to change.
3672  *
3673  * @see lcb_cntl()
3674  * @see lcb-cntl-settings
3675  */
3676 LIBCOUCHBASE_API
3677 lcb_error_t
3678 lcb_cntl_string(lcb_t instance, const char *key, const char *value);
3679 
3680 /**
3681 * @brief Convenience function to set a value as an lcb_U32
3682 * @param instance
3683 * @param cmd setting to modify
3684 * @param arg the new value
3685 * @return see lcb_cntl() for details
3686 * @committed
3687 */
3688 LIBCOUCHBASE_API
3689 lcb_error_t lcb_cntl_setu32(lcb_t instance, int cmd, lcb_U32 arg);
3690 
3691 /**
3692 * @brief Retrieve an lcb_U32 setting
3693 * @param instance
3694 * @param cmd setting to retrieve
3695 * @return the value.
3696 * @warning This function does not return an error code. Ensure that the cntl is
3697 * correct for this version, or use lcb_cntl() directly.
3698 * @committed
3699 */
3700 LIBCOUCHBASE_API
3701 lcb_U32 lcb_cntl_getu32(lcb_t instance, int cmd);
3702 
3703 /**
3704  * Determine if a specific control code exists
3705  * @param ctl the code to check for
3706  * @return 0 if it does not exist, nonzero if it exists.
3707  */
3708 LIBCOUCHBASE_API
3709 int
3710 lcb_cntl_exists(int ctl);
3711 /**@}*/ /* settings */
3712 
3713 /**
3714  * @ingroup lcb-public-api
3715  * @defgroup lcb-timings Timings
3716  * @brief Determine how long operations are taking to be completed
3717  *
3718  * libcouchbase provides a simple form of per-command timings you may use
3719  * to figure out the current lantency for the request-response cycle as
3720  * generated by your application. Please note that these numbers are not
3721  * necessarily accurate as you may affect the timing recorded by doing
3722  * work in the event loop.
3723  *
3724  * The time recorded with this library is the time elapsed from the
3725  * command being called, and the response packet being received from the
3726  * server.  Everything the application does before driving the event loop
3727  * will affect the timers.
3728  *
3729  * The function lcb_enable_timings() is used to enable the timings for
3730  * the given instance, and lcb_disable_timings is used to disable the
3731  * timings. The overhead of using the timers should be negligible.
3732  *
3733  * The function lcb_get_timings is used to retrieve the current timing.
3734  * values from the given instance. The cookie is passed transparently to
3735  * the callback function.
3736  *
3737  * Here is an example of the usage of this module:
3738  *
3739  * @code{.c}
3740  * #include <libcouchbase/couchbase.h>
3741  *
3742  * static void callback(
3743  *  lcb_t instance, const void *cookie, lcb_timeunit_t timeunit, lcb_U32 min,
3744  *  lcb_U32 max, lcb_U32 total, lcb_U32 maxtotal)
3745  * {
3746  *   FILE* out = (void*)cookie;
3747  *   int num = (float)10.0 * (float)total / ((float)maxtotal);
3748  *   fprintf(out, "[%3u - %3u]", min, max);
3749  *   switch (timeunit) {
3750  *   case LCB_TIMEUNIT_NSEC:
3751  *      fprintf(out, "ns");
3752  *      break;
3753  *   case LCB_TIMEUNIT_USEC:
3754  *      fprintf(out, "us");
3755  *      break;
3756  *   case LCB_TIMEUNIT_MSEC:
3757  *      fsprintf(out, "ms");
3758  *      break;
3759  *   case LCB_TIMEUNIT_SEC:
3760  *      fprintf(out, "s ");
3761  *      break;
3762  *   default:
3763  *      ;
3764  *   }
3765  *
3766  *   fprintf(out, " |");
3767  *   for (int ii = 0; ii < num; ++ii) {
3768  *      fprintf(out, "#");
3769  *   }
3770  *   fprintf(out, " - %u\n", total);
3771  * }
3772  *
3773  *
3774  * lcb_enable_timings(instance);
3775  * ... do a lot of operations ...
3776  * fprintf(stderr, "              +---------+\n"
3777  * lcb_get_timings(instance, stderr, callback);
3778  * fprintf(stderr, "              +---------+\n"
3779  * lcb_disable_timings(instance);
3780  * @endcode
3781  *
3782  * @addtogroup lcb-timings
3783  * @{
3784  */
3785 
3786 /**
3787  * @brief Time units reported by lcb_get_timings()
3788  */
3789 enum lcb_timeunit_t {
3790     LCB_TIMEUNIT_NSEC = 0, /**< @brief Time is in nanoseconds */
3791     LCB_TIMEUNIT_USEC = 1, /**< @brief Time is in microseconds */
3792     LCB_TIMEUNIT_MSEC = 2, /**< @brief Time is in milliseconds */
3793     LCB_TIMEUNIT_SEC = 3 /**< @brief Time is in seconds */
3794 };
3795 typedef enum lcb_timeunit_t lcb_timeunit_t;
3796 
3797 /**
3798  * Start recording timing metrics for the different operations.
3799  * The timer is started when the command is called (and the data
3800  * spooled to the server), and the execution time is the time until
3801  * we parse the response packets. This means that you can affect
3802  * the timers by doing a lot of other stuff before checking if
3803  * there is any results available..
3804  *
3805  * @param instance the handle to lcb
3806  * @return Status of the operation.
3807  * @committed
3808  */
3809 LIBCOUCHBASE_API
3810 lcb_error_t lcb_enable_timings(lcb_t instance);
3811 
3812 
3813 /**
3814  * Stop recording (and release all resources from previous measurements)
3815  * timing metrics.
3816  *
3817  * @param instance the handle to lcb
3818  * @return Status of the operation.
3819  * @committed
3820  */
3821 LIBCOUCHBASE_API
3822 lcb_error_t lcb_disable_timings(lcb_t instance);
3823 
3824 /**
3825  * The following function is called for each bucket in the timings
3826  * histogram when you call lcb_get_timings.
3827  * You are guaranteed that the callback will be called with the
3828  * lowest [min,max] range first.
3829  *
3830  * @param instance the handle to lcb
3831  * @param cookie the cookie you provided that allows you to pass
3832  *               arbitrary user data to the callback
3833  * @param timeunit the "scale" for the values
3834  * @param min The lower bound for this histogram bucket
3835  * @param max The upper bound for this histogram bucket
3836  * @param total The number of hits in this histogram bucket
3837  * @param maxtotal The highest value in all of the buckets
3838  */
3839 typedef void (*lcb_timings_callback)(lcb_t instance,
3840                                      const void *cookie,
3841                                      lcb_timeunit_t timeunit,
3842                                      lcb_U32 min,
3843                                      lcb_U32 max,
3844                                      lcb_U32 total,
3845                                      lcb_U32 maxtotal);
3846 
3847 /**
3848  * Get the timings histogram
3849  *
3850  * @param instance the handle to lcb
3851  * @param cookie a cookie that will be present in all of the callbacks
3852  * @param callback Callback to invoke which will handle the timings
3853  * @return Status of the operation.
3854  * @committed
3855  */
3856 LIBCOUCHBASE_API
3857 lcb_error_t lcb_get_timings(lcb_t instance,
3858                             const void *cookie,
3859                             lcb_timings_callback callback);
3860 /**@} (Group: Timings) */
3861 
3862 /**
3863 * @ingroup lcb-public-api
3864 * @defgroup lcb-build-info Build Information
3865 * @brief Get library version and supported features
3866 * @details
3867 * These functions and macros may be used to conditionally compile features
3868 * depending on the version of the library being used. They may also be used
3869 * to employ various features at runtime and to retrieve the version for
3870 * informational purposes.
3871 * @addtogroup lcb-build-info
3872 * @{
3873 */
3874 
3875 #if !defined(LCB_VERSION_STRING) || defined(__LCB_DOXYGEN__)
3876 /** @brief libcouchbase version string */
3877 #define LCB_VERSION_STRING "unknown"
3878 #endif
3879 
3880 #if !defined(LCB_VERSION) || defined(__LCB_DOXYGEN__)
3881 /**@brief libcouchbase hex version
3882  *
3883  * This number contains the hexadecimal representation of the library version.
3884  * It is in a format of `0xXXYYZZ` where `XX` is the two digit major version
3885  * (e.g. `02`), `YY` is the minor version (e.g. `05`) and `ZZ` is the patch
3886  * version (e.g. `24`).
3887  *
3888  * For example:
3889  *
3890  * String   |Hex
3891  * ---------|---------
3892  * 2.0.0    | 0x020000
3893  * 2.1.3    | 0x020103
3894  * 3.0.15   | 0x030015
3895  */
3896 #define LCB_VERSION 0x000000
3897 #endif
3898 
3899 #if !defined(LCB_VERSION_CHANGESET) || defined(__LCB_DOXYGEN__)
3900 /**@brief The SCM revision ID. @see LCB_CNTL_CHANGESET */
3901 #define LCB_VERSION_CHANGESET "0xdeadbeef"
3902 #endif
3903 
3904 /**
3905  * Get the version of the library.
3906  *
3907  * @param version where to store the numeric representation of the
3908  *         version (or NULL if you don't care)
3909  *
3910  * @return the textual description of the version ('\0'
3911  *          terminated). Do <b>not</b> try to release this string.
3912  *
3913  */
3914 LIBCOUCHBASE_API
3915 const char *lcb_get_version(lcb_U32 *version);
3916 
3917 /** Global/extern variable containing the version of the library */
3918 LIBCOUCHBASE_API LCB_EXTERN_VAR
3919 const lcb_U32 lcb_version_g;
3920 
3921 /**@brief Whether the library has SSL support*/
3922 #define LCB_SUPPORTS_SSL 1
3923 /**@brief Whether the library has experimental compression support */
3924 #define LCB_SUPPORTS_SNAPPY 2
3925 /**@brief Whether the library has experimental tracing support */
3926 #define LCB_SUPPORTS_TRACING 3
3927 
3928 /**
3929  * @committed
3930  * Determine if this version has support for a particularl feature
3931  * @param n the feature ID to check for
3932  * @return 0 if not supported, nonzero if supported.
3933  */
3934 LIBCOUCHBASE_API
3935 int
3936 lcb_supports_feature(int n);
3937 
3938 /**@} (Group: Build Info) */
3939 
3940 
3941 /**
3942  * Functions to allocate and free memory related to libcouchbase. This is
3943  * mainly for use on Windows where it is possible that the DLL and EXE
3944  * are using two different CRTs
3945  */
3946 LIBCOUCHBASE_API
3947 void *lcb_mem_alloc(lcb_SIZE size);
3948 
3949 /** Use this to free memory allocated with lcb_mem_alloc */
3950 LIBCOUCHBASE_API
3951 void lcb_mem_free(void *ptr);
3952 
3953 /**
3954  * @internal
3955  *
3956  * These two functions unconditionally start and stop the event loop. These
3957  * should be used _only_ when necessary. Use lcb_wait and lcb_breakout
3958  * for safer variants.
3959  *
3960  * Internally these proxy to the run_event_loop/stop_event_loop calls
3961  */
3962 LCB_INTERNAL_API
3963 void lcb_run_loop(lcb_t instance);
3964 
3965 /** @internal */
3966 LCB_INTERNAL_API
3967 void lcb_stop_loop(lcb_t instance);
3968 
3969 /** @internal */
3970 /* This returns the library's idea of time */
3971 LCB_INTERNAL_API
3972 lcb_U64 lcb_nstime(void);
3973 
3974 typedef enum {
3975     /** Dump the raw vbucket configuration */
3976     LCB_DUMP_VBCONFIG =  0x01,
3977     /** Dump information about each packet */
3978     LCB_DUMP_PKTINFO = 0x02,
3979     /** Dump memory usage/reservation information about buffers */
3980     LCB_DUMP_BUFINFO = 0x04,
3981     /** Dump various metrics information */
3982     LCB_DUMP_METRICS = 0x08,
3983     /** Dump everything */
3984     LCB_DUMP_ALL = 0xff
3985 } lcb_DUMPFLAGS;
3986 
3987 /** Volatile histogram APIs, used by pillowfight and others */
3988 struct lcb_histogram_st;
3989 typedef struct lcb_histogram_st lcb_HISTOGRAM;
3990 
3991 /**
3992  * @volatile
3993  * Create a histogram structure
3994  * @return a new histogram structure
3995  */
3996 LIBCOUCHBASE_API
3997 lcb_HISTOGRAM *
3998 lcb_histogram_create(void);
3999 
4000 /**
4001  * @volatile free a histogram structure
4002  * @param hg the histogram
4003  */
4004 LIBCOUCHBASE_API
4005 void
4006 lcb_histogram_destroy(lcb_HISTOGRAM *hg);
4007 
4008 /**
4009  * @volatile
4010  * Add an entry to a histogram structure
4011  * @param hg the histogram
4012  * @param duration the duration in nanoseconds
4013  */
4014 LIBCOUCHBASE_API
4015 void
4016 lcb_histogram_record(lcb_HISTOGRAM *hg, lcb_U64 duration);
4017 
4018 typedef void (*lcb_HISTOGRAM_CALLBACK)
4019         (const void *cookie, lcb_timeunit_t timeunit, lcb_U32 min, lcb_U32 max,
4020                 lcb_U32 total, lcb_U32 maxtotal);
4021 
4022 /**
4023  * @volatile
4024  * Repeatedly invoke a callback for all entries in the histogram
4025  * @param hg the histogram
4026  * @param cookie pointer passed to callback
4027  * @param cb callback to invoke
4028  */
4029 LIBCOUCHBASE_API
4030 void
4031 lcb_histogram_read(const lcb_HISTOGRAM *hg, const void *cookie,
4032     lcb_HISTOGRAM_CALLBACK cb);
4033 
4034 /**
4035  * Print the histogram to the specified FILE.
4036  *
4037  * This essentially outputs the same raw information as lcb_histogram_read(),
4038  * except it prints in implementation-defined format. It's simpler to use
4039  * than lcb_histogram_read, but less flexible.
4040  *
4041  * @param hg the histogram
4042  * @param stream File to print the histogram to.
4043  */
4044 LIBCOUCHBASE_API
4045 void lcb_histogram_print(lcb_HISTOGRAM* hg, FILE* stream);
4046 
4047 /**
4048  * @volatile
4049  *
4050  * Retrieves the extra error context from the response structure.
4051  *
4052  * This context does not duplicate information described by status
4053  * code rendered by lcb_strerror() function, and should be logged
4054  * if available.
4055  *
4056  * @return the pointer to string or NULL if context wasn't specified.
4057  */
4058 LIBCOUCHBASE_API
4059 const char *
4060 lcb_resp_get_error_context(int cbtype, const lcb_RESPBASE *rb);
4061 
4062 /**
4063  * @uncommitted
4064  *
4065  * Retrieves the error reference id from the response structure.
4066  *
4067  * Error reference id (or event id) should be logged to allow
4068  * administrators match client-side events with cluster logs.
4069  *
4070  * @return the pointer to string or NULL if ref wasn't specified.
4071  */
4072 LIBCOUCHBASE_API
4073 const char *
4074 lcb_resp_get_error_ref(int cbtype, const lcb_RESPBASE *rb);
4075 
4076 /**
4077  * @volatile
4078  * Returns whether the library redacting logs for this connection instance.
4079  *
4080  * @return non-zero if the logs are being redacted for this instance.
4081  */
4082 LIBCOUCHBASE_API
4083 int lcb_is_redacting_logs(lcb_t instance);
4084 
4085 /* Post-include some other headers */
4086 #ifdef __cplusplus
4087 }
4088 #endif /* __cplusplus */
4089 #include <libcouchbase/subdoc.h>
4090 #include <libcouchbase/deprecated.h>
4091 #include <libcouchbase/api-legacy.h>
4092 #endif /* LIBCOUCHBASE_COUCHBASE_H */
4093