Fetching contributors…
Cannot retrieve contributors at this time
679 lines (637 sloc) 23.9 KB
/* vim: ft=c et ts=8 sts=4 sw=4 cino=
* Copyright 2011, 2012 Couchbase, Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* See the License for the specific language governing permissions and
* limitations under the License.
#include "couchbase_config.h"
#if defined(_WIN32) && defined(__cplusplus)
#include <cstdint>
#include <stdint.h>
#include <ruby.h>
#ifndef RUBY_ST_H
#include <st.h>
#if defined(HAVE_RB_FIBER_YIELD) && !defined(_WIN32)
#include <ruby/thread.h>
typedef uint64_t hrtime_t;
extern hrtime_t gethrtime(void);
#include <sys/socket.h>
#include <fcntl.h>
#include <errno.h>
#include <libcouchbase/couchbase.h>
#include <libcouchbase/n1ql.h>
#include "ruby/encoding.h"
#define STR_NEW(ptr, len) rb_external_str_new((ptr), (len))
#define STR_NEW_CSTR(str) rb_external_str_new_cstr((str))
#define STR_NEW(ptr, len) rb_str_new((ptr), (len))
#define STR_NEW_CSTR(str) rb_str_new2((str))
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#include <varargs.h>
#define va_init_list(a,b) va_start(a)
VALUE rb_hash_lookup2(VALUE, VALUE, VALUE);
typedef st_data_t st_index_t;
#define cb_debug_object(OBJ) do { \
VALUE debug_args[6] = { \
rb_funcall(OBJ, rb_intern("object_id"), 0), \
STR_NEW_CSTR(" "), \
rb_funcall(OBJ, rb_intern("class"), 0), \
STR_NEW_CSTR(" "), \
rb_funcall(OBJ, rb_intern("inspect"), 0), \
STR_NEW_CSTR("\n") }; \
rb_funcall2(rb_stderr, rb_intern("print"), 6, debug_args); \
} while(0)
#define CB_FMT_MASK 0x3
#define CB_FMT_DOCUMENT 0x0
#define CB_FMT_MARSHAL 0x1
#define CB_FMT_PLAIN 0x2
/* Structs */
struct cb_bucket_st
lcb_t handle;
lcb_type_t type;
struct lcb_io_opt_st *io;
uint16_t port;
VALUE authority;
VALUE hostname;
VALUE pool;
VALUE bucket;
VALUE username;
VALUE password;
VALUE engine;
int async;
int quiet;
uint8_t connected; /* non-zero if instance has been connected. it is possible to defer connection with :async option */
uint8_t running; /* non-zero if event loop is running */
uint8_t trigger_connect_cb_on_set; /* if non-zero, the on_connect callback will be triggered immediately after set */
VALUE transcoder;
uint32_t default_flags;
time_t default_ttl;
time_t default_observe_timeout;
lcb_uint64_t default_arith_create; /* should the incr/decr create the key? if non-zero, will use arith_init */
lcb_uint64_t default_arith_init; /* default initial value for incr/decr */
uint32_t timeout;
size_t threshold; /* the number of bytes to trigger event loop, zero if don't care */
size_t nbytes; /* the number of bytes scheduled to be sent */
VALUE exception; /* error delivered by error_callback */
VALUE on_error_proc; /* is using to deliver errors in async mode */
VALUE on_connect_proc; /* used to notify that instance ready to handle requests in async mode */
VALUE environment; /* sym_development or sym_production */
VALUE key_prefix_val;
VALUE node_list;
VALUE bootstrap_transports;
st_table *object_space;
char destroying;
char async_disconnect_hook_set;
VALUE self; /* the pointer to bucket representation in ruby land */
struct cb_http_request_st;
struct cb_context_st
struct cb_bucket_st* bucket;
int extended;
VALUE proc;
VALUE exception;
VALUE observe_options;
VALUE transcoder;
VALUE transcoder_opts;
VALUE operation;
VALUE headers_val;
int headers_built;
struct cb_http_request_st *request;
int quiet;
int arith; /* incr: +1, decr: -1, other: 0 */
int all_replicas; /* handle multiple responses from get_replica if non-zero */
size_t nqueries;
struct cb_http_request_st {
struct cb_bucket_st *bucket;
VALUE bucket_obj;
VALUE type;
int extended;
int running;
int completed;
lcb_http_request_t request;
lcb_http_cmd_t cmd;
struct cb_context_st *ctx;
VALUE on_body_callback;
struct cb_timer_st
struct cb_bucket_st *bucket;
int periodic;
uint32_t usec;
lcb_timer_t timer;
VALUE self;
VALUE callback;
/* Classes */
extern VALUE cb_cBucket;
extern VALUE cb_cCouchRequest;
extern VALUE cb_cResult;
extern VALUE cb_cTimer;
/* Modules */
extern VALUE cb_mCouchbase;
extern VALUE cb_mError;
extern VALUE cb_mTranscoder;
extern VALUE cb_mDocument;
extern VALUE cb_mPlain;
extern VALUE cb_mMarshal;
extern VALUE cb_mURI;
extern VALUE cb_mMultiJson;
extern VALUE em_m;
/* Symbols */
extern ID cb_sym_add;
extern ID cb_sym_all;
extern ID cb_sym_append;
extern ID cb_sym_assemble_hash;
extern ID cb_sym_async;
extern ID cb_sym_body;
extern ID cb_sym_bootstrap_transports;
extern ID cb_sym_bucket;
extern ID cb_sym_cas;
extern ID cb_sym_cccp;
extern ID cb_sym_chunked;
extern ID cb_sym_cluster;
extern ID cb_sym_connect;
extern ID cb_sym_content_type;
extern ID cb_sym_create;
extern ID cb_sym_decrement;
extern ID cb_sym_default;
extern ID cb_sym_default_arithmetic_init;
extern ID cb_sym_default_flags;
extern ID cb_sym_default_format;
extern ID cb_sym_default_observe_timeout;
extern ID cb_sym_default_ttl;
extern ID cb_sym_delete;
extern ID cb_sym_delta;
extern ID cb_sym_development;
extern ID cb_sym_document;
extern ID cb_sym_engine;
extern ID cb_sym_environment;
extern ID cb_sym_eventmachine;
extern ID cb_sym_extended;
extern ID cb_sym_first;
extern ID cb_sym_flags;
extern ID cb_sym_forced;
extern ID cb_sym_format;
extern ID cb_sym_found;
extern ID cb_sym_get;
extern ID cb_sym_host;
extern ID cb_sym_hostname;
extern ID cb_sym_http;
extern ID cb_sym_http_request;
extern ID cb_sym_increment;
extern ID cb_sym_initial;
extern ID cb_sym_iocp;
extern ID cb_sym_key_prefix;
extern ID cb_sym_libev;
extern ID cb_sym_libevent;
extern ID cb_sym_lock;
extern ID cb_sym_management;
extern ID cb_sym_marshal;
extern ID cb_sym_method;
extern ID cb_sym_node_list;
extern ID cb_sym_not_found;
extern ID cb_sym_num_replicas;
extern ID cb_sym_observe;
extern ID cb_sym_password;
extern ID cb_sym_periodic;
extern ID cb_sym_persisted;
extern ID cb_sym_plain;
extern ID cb_sym_pool;
extern ID cb_sym_port;
extern ID cb_sym_post;
extern ID cb_sym_prepend;
extern ID cb_sym_production;
extern ID cb_sym_put;
extern ID cb_sym_quiet;
extern ID cb_sym_replace;
extern ID cb_sym_replica;
extern ID cb_sym_rows;
extern ID cb_sym_meta;
extern ID cb_sym_select;
extern ID cb_sym_send_threshold;
extern ID cb_sym_set;
extern ID cb_sym_stats;
extern ID cb_sym_timeout;
extern ID cb_sym_touch;
extern ID cb_sym_transcoder;
extern ID cb_sym_ttl;
extern ID cb_sym_type;
extern ID cb_sym_unlock;
extern ID cb_sym_username;
extern ID cb_sym_version;
extern ID cb_sym_view;
extern ID cb_id_add_shutdown_hook;
extern ID cb_id_arity;
extern ID cb_id_call;
extern ID cb_id_create_timer;
extern ID cb_id_delete;
extern ID cb_id_dump;
extern ID cb_id_dup;
extern ID cb_id_flatten_bang;
extern ID cb_id_has_key_p;
extern ID cb_id_host;
extern ID cb_id_iv_body;
extern ID cb_id_iv_cas;
extern ID cb_id_iv_completed;
extern ID cb_id_iv_error;
extern ID cb_id_iv_flags;
extern ID cb_id_iv_from_master;
extern ID cb_id_iv_headers;
extern ID cb_id_iv_meta;
extern ID cb_id_iv_inner_exception;
extern ID cb_id_iv_key;
extern ID cb_id_iv_node;
extern ID cb_id_iv_operation;
extern ID cb_id_iv_status;
extern ID cb_id_iv_time_to_persist;
extern ID cb_id_iv_time_to_replicate;
extern ID cb_id_iv_value;
extern ID cb_id_load;
extern ID cb_id_match;
extern ID cb_id_next_tick;
extern ID cb_id_observe_and_wait;
extern ID cb_id_parse;
extern ID cb_id_parse_body_bang;
extern ID cb_id_password;
extern ID cb_id_path;
extern ID cb_id_port;
extern ID cb_id_scheme;
extern ID cb_id_sprintf;
extern ID cb_id_to_s;
extern ID cb_id_user;
extern ID cb_id_verify_observe_options;
/* Errors */
extern VALUE cb_eBaseError;
extern VALUE cb_eValueFormatError;
extern VALUE cb_eHTTPError;
extern VALUE cb_eQuery;
/* LCB_SUCCESS = 0x00 */
/* LCB_AUTH_CONTINUE = 0x01 */
extern VALUE cb_eAuthError; /* LCB_AUTH_ERROR = 0x02 */
extern VALUE cb_eDeltaBadvalError; /* LCB_DELTA_BADVAL = 0x03 */
extern VALUE cb_eTooBigError; /* LCB_E2BIG = 0x04 */
extern VALUE cb_eBusyError; /* LCB_EBUSY = 0x05 */
extern VALUE cb_eInternalError; /* LCB_EINTERNAL = 0x06 */
extern VALUE cb_eInvalidError; /* LCB_EINVAL = 0x07 */
extern VALUE cb_eNoMemoryError; /* LCB_ENOMEM = 0x08 */
extern VALUE cb_eRangeError; /* LCB_ERANGE = 0x09 */
extern VALUE cb_eLibcouchbaseError; /* LCB_ERROR = 0x0a */
extern VALUE cb_eTmpFailError; /* LCB_ETMPFAIL = 0x0b */
extern VALUE cb_eKeyExistsError; /* LCB_KEY_EEXISTS = 0x0c */
extern VALUE cb_eNotFoundError; /* LCB_KEY_ENOENT = 0x0d */
extern VALUE cb_eDlopenFailedError; /* LCB_DLOPEN_FAILED = 0x0e */
extern VALUE cb_eDlsymFailedError; /* LCB_DLSYM_FAILED = 0x0f */
extern VALUE cb_eNetworkError; /* LCB_NETWORK_ERROR = 0x10 */
extern VALUE cb_eNotMyVbucketError; /* LCB_NOT_MY_VBUCKET = 0x11 */
extern VALUE cb_eNotStoredError; /* LCB_NOT_STORED = 0x12 */
extern VALUE cb_eNotSupportedError; /* LCB_NOT_SUPPORTED = 0x13 */
extern VALUE cb_eUnknownCommandError; /* LCB_UNKNOWN_COMMAND = 0x14 */
extern VALUE cb_eUnknownHostError; /* LCB_UNKNOWN_HOST = 0x15 */
extern VALUE cb_eProtocolError; /* LCB_PROTOCOL_ERROR = 0x16 */
extern VALUE cb_eTimeoutError; /* LCB_ETIMEDOUT = 0x17 */
extern VALUE cb_eConnectError; /* LCB_CONNECT_ERROR = 0x18 */
extern VALUE cb_eBucketNotFoundError; /* LCB_BUCKET_ENOENT = 0x19 */
extern VALUE cb_eClientNoMemoryError; /* LCB_CLIENT_ENOMEM = 0x1a */
extern VALUE cb_eClientTmpFailError; /* LCB_CLIENT_ETMPFAIL = 0x1b */
extern VALUE cb_eBadHandleError; /* LCB_EBADHANDLE = 0x1c */
extern VALUE cb_eServerBug; /* LCB_SERVER_BUG = 0x1d */
extern VALUE cb_ePluginVersionMismatch; /* LCB_PLUGIN_VERSION_MISMATCH = 0x1e */
extern VALUE cb_eInvalidHostFormat; /* LCB_INVALID_HOST_FORMAT = 0x1f */
extern VALUE cb_eInvalidChar; /* LCB_INVALID_CHAR = 0x20 */
extern VALUE cb_eDurabilityTooMany; /* LCB_DURABILITY_ETOOMANY = 0x21 */
extern VALUE cb_eDuplicateCommands; /* LCB_DUPLICATE_COMMANDS = 0x22 */
extern VALUE cb_eNoMatchingServer; /* LCB_NO_MATCHING_SERVER = 0x23 */
extern VALUE cb_eBadEnvironment; /* LCB_BAD_ENVIRONMENT = 0x24 */
extern VALUE cb_eBusy; /* LCB_BUSY = 0x25 */
extern VALUE cb_eInvalidUsername; /* LCB_INVALID_USERNAME = 0x26 */
/* Default Strings */
extern VALUE cb_vStrDefault;
extern VALUE cb_vStrEmpty;
extern VALUE cb_vStrLocalhost;
typedef void (*mark_f)(void *, struct cb_bucket_st*);
void cb_strip_key_prefix(struct cb_bucket_st *bucket, VALUE key);
VALUE cb_check_error(lcb_error_t rc, const char *msg, VALUE key);
VALUE cb_check_error_with_status(lcb_error_t rc, const char *msg, VALUE key, lcb_http_status_t status);
int cb_bucket_connected_bang(struct cb_bucket_st *bucket, VALUE operation);
void cb_gc_protect_ptr(struct cb_bucket_st *bucket, void *ptr, mark_f mark_func);
void cb_gc_unprotect_ptr(struct cb_bucket_st *bucket, void *ptr);
VALUE cb_proc_call(struct cb_bucket_st *bucket, VALUE recv, int argc, ...);
int cb_first_value_i(VALUE key, VALUE value, VALUE arg);
void cb_build_headers(struct cb_context_st *ctx, const char * const *headers);
void cb_maybe_do_loop(struct cb_bucket_st *bucket);
VALUE cb_unify_key(struct cb_bucket_st *bucket, VALUE key, int apply_prefix);
VALUE cb_encode_value(VALUE transcoder, VALUE val, uint32_t *flags, VALUE options);
VALUE cb_decode_value(VALUE transcoder, VALUE blob, uint32_t flags, VALUE options);
void cb_async_error_notify(struct cb_bucket_st *bucket, VALUE exc);
void cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation, lcb_error_t error, const lcb_store_resp_t *resp);
void cb_get_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_get_resp_t *resp);
void cb_touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_touch_resp_t *resp);
void cb_delete_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_remove_resp_t *resp);
void cb_stat_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_server_stat_resp_t *resp);
void cb_arithmetic_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_arithmetic_resp_t *resp);
void cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_server_version_resp_t *resp);
void cb_http_complete_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp);
void cb_http_data_callback(lcb_http_request_t request, lcb_t handle, const void *cookie, lcb_error_t error, const lcb_http_resp_t *resp);
void cb_observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_observe_resp_t *resp);
void cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_unlock_resp_t *resp);
struct cb_context_st *cb_context_alloc(struct cb_bucket_st *bucket);
struct cb_context_st *cb_context_alloc_common(struct cb_bucket_st *bucket, VALUE proc, size_t nqueries);
void cb_context_free(struct cb_context_st *ctx);
VALUE cb_bucket_alloc(VALUE klass);
void cb_bucket_free(void *ptr);
VALUE cb_bucket_init_copy(VALUE copy, VALUE orig);
VALUE cb_bucket_init(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_inspect(VALUE self);
VALUE cb_bucket_touch(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_delete(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_stats(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_set(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_add(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_replace(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_append(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_prepend(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_aset(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_get(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_incr(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_decr(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_unlock(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_query(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_run(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_stop(VALUE self);
VALUE cb_bucket_version(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_disconnect(VALUE self);
VALUE cb_bucket_reconnect(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_make_http_request(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_observe(int argc, VALUE *argv, VALUE self);
VALUE cb_bucket_connected_p(VALUE self);
VALUE cb_bucket_async_p(VALUE self);
VALUE cb_bucket_quiet_get(VALUE self);
VALUE cb_bucket_quiet_set(VALUE self, VALUE val);
VALUE cb_bucket_transcoder_get(VALUE self);
VALUE cb_bucket_transcoder_set(VALUE self, VALUE val);
VALUE cb_bucket_default_flags_get(VALUE self);
VALUE cb_bucket_default_flags_set(VALUE self, VALUE val);
VALUE cb_bucket_default_format_get(VALUE self);
VALUE cb_bucket_default_format_set(VALUE self, VALUE val);
VALUE cb_bucket_on_error_set(VALUE self, VALUE val);
VALUE cb_bucket_on_error_get(VALUE self);
VALUE cb_bucket_on_connect_set(VALUE self, VALUE val);
VALUE cb_bucket_on_connect_get(VALUE self);
VALUE cb_bucket_timeout_get(VALUE self);
VALUE cb_bucket_timeout_set(VALUE self, VALUE val);
VALUE cb_bucket_key_prefix_get(VALUE self);
VALUE cb_bucket_key_prefix_set(VALUE self, VALUE val);
VALUE cb_bucket_url_get(VALUE self);
VALUE cb_bucket_hostname_get(VALUE self);
VALUE cb_bucket_port_get(VALUE self);
VALUE cb_bucket_authority_get(VALUE self);
VALUE cb_bucket_bucket_get(VALUE self);
VALUE cb_bucket_pool_get(VALUE self);
VALUE cb_bucket_username_get(VALUE self);
VALUE cb_bucket_password_get(VALUE self);
VALUE cb_bucket_environment_get(VALUE self);
VALUE cb_bucket_num_replicas_get(VALUE self);
VALUE cb_bucket_default_observe_timeout_get(VALUE self);
VALUE cb_bucket_default_observe_timeout_set(VALUE self, VALUE val);
VALUE cb_bucket_default_arithmetic_init_get(VALUE self);
VALUE cb_bucket_default_arithmetic_init_set(VALUE self, VALUE val);
VALUE cb_http_request_alloc(VALUE klass);
VALUE cb_http_request_init(int argc, VALUE *argv, VALUE self);
VALUE cb_http_request_inspect(VALUE self);
VALUE cb_http_request_on_body(VALUE self);
VALUE cb_http_request_perform(VALUE self);
VALUE cb_http_request_pause(VALUE self);
VALUE cb_http_request_continue(VALUE self);
VALUE cb_http_request_path_get(VALUE self);
VALUE cb_http_request_extended_get(VALUE self);
VALUE cb_http_request_chunked_get(VALUE self);
VALUE cb_result_success_p(VALUE self);
VALUE cb_result_inspect(VALUE self);
VALUE cb_timer_alloc(VALUE klass);
VALUE cb_timer_inspect(VALUE self);
VALUE cb_timer_cancel(VALUE self);
VALUE cb_timer_init(int argc, VALUE *argv, VALUE self);
/* Method arguments */
enum cb_command_t {
cb_cmd_touch = 0x01,
cb_cmd_remove = 0x02,
cb_cmd_store = 0x03,
cb_cmd_get = 0x04,
cb_cmd_arith = 0x05,
cb_cmd_stats = 0x06,
cb_cmd_version = 0x08,
cb_cmd_observe = 0x09,
cb_cmd_unlock = 0x10
struct cb_params_st
enum cb_command_t type;
union {
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_touch_cmd_t *items;
/* array of the pointers to the items */
const lcb_touch_cmd_t **ptr;
unsigned int quiet : 1;
unsigned int array : 1;
lcb_time_t ttl;
} touch;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_remove_cmd_t *items;
/* array of the pointers to the items */
const lcb_remove_cmd_t **ptr;
unsigned int array : 1;
/* 1 if it should silense NOT_FOUND errors */
unsigned int quiet : 1;
lcb_cas_t cas;
} remove;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_store_cmd_t *items;
/* array of the pointers to the items */
const lcb_store_cmd_t **ptr;
lcb_storage_t operation;
lcb_uint32_t flags;
lcb_time_t ttl;
lcb_cas_t cas;
lcb_datatype_t datatype;
VALUE observe;
VALUE transcoder;
VALUE transcoder_opts;
} store;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_get_cmd_t *items;
/* array of the pointers to the items */
const lcb_get_cmd_t **ptr;
/* array of the items for GET_REPLICA command */
lcb_get_replica_cmd_t *items_gr;
/* array of the pointers to the items for GET_REPLICA command */
const lcb_get_replica_cmd_t **ptr_gr;
unsigned int array : 1;
unsigned int lock : 1;
unsigned int assemble_hash : 1;
unsigned int extended : 1;
unsigned int quiet : 1;
/* arguments given in form of hash key-ttl to "get and touch" */
unsigned int gat : 1;
lcb_time_t ttl;
VALUE replica;
VALUE transcoder;
VALUE transcoder_opts;
VALUE keys_ary;
} get;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_arithmetic_cmd_t *items;
/* array of the pointers to the items */
const lcb_arithmetic_cmd_t **ptr;
unsigned int array : 1;
unsigned int extended : 1;
unsigned int create : 1;
lcb_time_t ttl;
lcb_uint64_t initial;
lcb_uint64_t delta;
int sign;
VALUE transcoder;
VALUE transcoder_opts;
lcb_datatype_t datatype;
} arith;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_server_stats_cmd_t *items;
/* array of the pointers to the items */
const lcb_server_stats_cmd_t **ptr;
unsigned int array : 1;
} stats;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_server_version_cmd_t *items;
/* array of the pointers to the items */
const lcb_server_version_cmd_t **ptr;
} version;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_observe_cmd_t *items;
/* array of the pointers to the items */
const lcb_observe_cmd_t **ptr;
unsigned int array : 1;
} observe;
struct {
/* number of items */
size_t num;
/* array of the items */
lcb_unlock_cmd_t *items;
/* array of the pointers to the items */
const lcb_unlock_cmd_t **ptr;
unsigned int quiet : 1;
lcb_cas_t cas;
} unlock;
} cmd;
struct cb_bucket_st *bucket;
/* helper index for iterators */
size_t idx;
/* the approximate size of the data to be sent */
size_t npayload;
VALUE ensurance;
VALUE args;
void cb_params_destroy(struct cb_params_st *params);
void cb_params_build(struct cb_params_st *params);
/* common plugin functions */
lcb_ssize_t cb_io_recv(struct lcb_io_opt_st *iops, lcb_socket_t sock, void *buffer, lcb_size_t len, int flags);
lcb_ssize_t cb_io_recvv(struct lcb_io_opt_st *iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov);
lcb_ssize_t cb_io_send(struct lcb_io_opt_st *iops, lcb_socket_t sock, const void *msg, lcb_size_t len, int flags);
lcb_ssize_t cb_io_sendv(struct lcb_io_opt_st *iops, lcb_socket_t sock, struct lcb_iovec_st *iov, lcb_size_t niov);
lcb_socket_t cb_io_socket(struct lcb_io_opt_st *iops, int domain, int type, int protocol);
void cb_io_close(struct lcb_io_opt_st *iops, lcb_socket_t sock);
int cb_io_connect(struct lcb_io_opt_st *iops, lcb_socket_t sock, const struct sockaddr *name, unsigned int namelen);
/* plugin init functions */
lcb_error_t cb_create_ruby_mt_io_opts(int version, lcb_io_opt_t *io, void *arg);
lcb_error_t cb_create_ruby_em_io_opts(int version, lcb_io_opt_t *io, void *arg);
/* shortcut functions */
static inline VALUE
rb_funcall_0(VALUE self, ID method)
return rb_funcall2(self, method, 0, NULL);
static inline VALUE
rb_funcall_1(VALUE self, ID method, VALUE arg)
return rb_funcall2(self, method, 1, &arg);
static inline VALUE
rb_funcall_2(VALUE self, ID method, VALUE arg1, VALUE arg2)
VALUE args[2] = {arg1, arg2};
return rb_funcall2(self, method, 2, args);