Ejemplo n.º 1
0
int couchbase_add(cachedb_con *connection,str *attr,int val,int expires,int *new_val)
{
	lcb_t instance;
	lcb_error_t oprc;
	lcb_arithmetic_cmd_t cmd;
	const lcb_arithmetic_cmd_t *commands[1];

	instance = COUCHBASE_CON(connection);

	commands[0] = &cmd;
	memset(&cmd, 0, sizeof(cmd));
	cmd.v.v0.key = attr->s;
	cmd.v.v0.nkey = attr->len;
	cmd.v.v0.delta = val;
	cmd.v.v0.create = 1;
	cmd.v.v0.initial = val;
	cmd.v.v0.exptime = expires;
	oprc = lcb_arithmetic(instance, NULL, 1, commands);

	if (oprc != LCB_SUCCESS) {
		if (oprc == LCB_KEY_ENOENT) {
			return -1;
		}

		LM_ERR("Failed to send the arithmetic query - %s\n", lcb_strerror(instance, oprc));
		//Attempt reconnect
		if (couchbase_conditional_reconnect(connection, oprc) != 1) {
			return -2;
		}

		//Try again
		instance = COUCHBASE_CON(connection);
		oprc = lcb_arithmetic(instance, NULL, 1, commands);

		if (oprc != LCB_SUCCESS) {
			if (oprc == LCB_KEY_ENOENT) {
				LM_ERR("Arithmetic command successfully retried\n");
				return -1;
			}
			LM_ERR("Arithmetic command retry failed - %s\n", lcb_strerror(instance, oprc));
			return -2;
		}
		LM_ERR("Arithmetic command successfully retried\n");
	}

	if (new_val)
		*new_val = arithmetic_res;

	return 1;
}
Ejemplo n.º 2
0
Archivo: cb.c Proyecto: muut/cberl
ERL_NIF_TERM cb_arithmetic(ErlNifEnv* env, handle_t* handle, void* obj)
{
    arithmetic_args_t* args = (arithmetic_args_t*)obj;

    struct libcouchbase_callback cb;

    lcb_error_t ret; //for checking responses

    lcb_arithmetic_cmd_t arithmetic;
    const lcb_arithmetic_cmd_t* commands[1];
    commands[0] = &arithmetic;
    memset(&arithmetic, 0, sizeof(arithmetic));
    arithmetic.v.v0.key = args->key;
    arithmetic.v.v0.nkey = args->nkey;
    arithmetic.v.v0.initial = args->initial;
    arithmetic.v.v0.create = args->create;
    arithmetic.v.v0.delta = args->delta;
    arithmetic.v.v0.exptime = args->exp;
    ret = lcb_arithmetic(handle->instance, &cb, 1, commands);

    free(args->key);
    if (ret != LCB_SUCCESS) {
        return return_lcb_error(env, ret);
    }
    lcb_wait(handle->instance);
    if(cb.error != LCB_SUCCESS) {
        return return_lcb_error(env, cb.error);
    }
    return enif_make_tuple2(env, A_OK(env), return_value(env, &cb));
}
Ejemplo n.º 3
0
// Given an LCB instance and a key name, create an arithmetic, and
// wait until it finishes, and if there is an error, display it.
static void OrigrBlockingArithmeticCreate(lcb_t instance, char *keyName, int expTimeSeconds) {

  int keyLength = strlen(keyName);

  lcb_error_t           arithmeticCreateErrorCode = 0;
  lcb_arithmetic_cmd_t *arithmeticCommand         = calloc(1, sizeof(*arithmeticCommand));

  arithmeticCommand->version      = 0;
  arithmeticCommand->v.v0.key     = keyName;
  arithmeticCommand->v.v0.nkey    = keyLength;
  arithmeticCommand->v.v0.exptime = expTimeSeconds; 
  arithmeticCommand->v.v0.create  = 1;
  arithmeticCommand->v.v0.delta   = 1;
  arithmeticCommand->v.v0.initial = 1234500;

  const lcb_arithmetic_cmd_t* arithCommands[] = { arithmeticCommand };

  arithmeticCreateErrorCode = lcb_arithmetic(instance, NULL, 1, arithCommands);
  if (arithmeticCreateErrorCode != LCB_SUCCESS) {
    printf("Couldn't schedule arithmeetic create operation!\n");
    printf("lcb_arithmetic errorCode is 0x%.8X \n", arithmeticCreateErrorCode);
    exit(1);
  }

  printf("Arithmetic CREATE: About to do lcb_wait()...\n");
  lcb_wait(instance); 
  printf("Arithmetic CREATE: Back from lcb_wait()...\n");

} // end of blockingArithmeticCreate()
Ejemplo n.º 4
0
// Given an LCB instance and a key name, increment an arithmetic, and
// wait until it finishes, and if there is an error, display it.
static void OrigBlockingArithmeticIncrement(lcb_t instance, char *keyName) {

  int keyLength = strlen(keyName);

  lcb_error_t           arithmeticIncrementErrorCode = 0;
  lcb_arithmetic_cmd_t *arithmeticCommand         = calloc(1, sizeof(*arithmeticCommand));

  arithmeticCommand->version      = 0;		// Determine if this is factor 
  arithmeticCommand->v.v0.key     = keyName;
  arithmeticCommand->v.v0.nkey    = keyLength;
  arithmeticCommand->v.v0.create  = 0;	 	// as opposed to 1
  arithmeticCommand->v.v0.delta   = 1;		// increment by one

  const lcb_arithmetic_cmd_t* arithCommands[] = { arithmeticCommand };

  arithmeticIncrementErrorCode = lcb_arithmetic(instance, NULL, 1, arithCommands);
  if (arithmeticIncrementErrorCode != LCB_SUCCESS) {
    printf("Couldn't schedule arithmetic increment operation!\n");
    printf("lcb_arithmetic errorCode is 0x%.8X \n", arithmeticIncrementErrorCode);
    exit(1);
  }

  printf("Arithmetic CREATE: About to do lcb_wait()...\n");
  lcb_wait(instance); 
  printf("Arithmetic CREATE: Back from lcb_wait()...\n");

} // end of blockingArithmeticIncrement()
Ejemplo n.º 5
0
// Given an LCB instance and a key name, increment an arithmetic, and
// wait until it finishes, and if there is an error, display it.
static void blockingArithmeticIncrement2(lcb_t instance, char *keyName) {

  int keyLength = strlen(keyName);

  lcb_error_t           arithmeticIncrementErrorCode = 0;
  lcb_arithmetic_cmd_t *arithmeticCommand         = calloc(1, sizeof(*arithmeticCommand));

  // These are the exact values
  arithmeticCommand->version      = 0;		
  arithmeticCommand->v.v0.key     = keyName;
  arithmeticCommand->v.v0.nkey    = strlen(keyName);
  arithmeticCommand->v.v0.exptime = 0;
  arithmeticCommand->v.v0.create  = 1;	 	
  arithmeticCommand->v.v0.delta   = 1;	 // Unknown since not printed in logs
  arithmeticCommand->v.v0.initial = 1;   // Equal to delta	

  const lcb_arithmetic_cmd_t* arithCommands[] = { arithmeticCommand };

  arithmeticIncrementErrorCode = lcb_arithmetic(instance, NULL, 1, arithCommands);
  if (arithmeticIncrementErrorCode != LCB_SUCCESS) {
    printf("Couldn't schedule increment operation!\n");
    printf("lcb_arithmetic errorCode is 0x%.8X \n", arithmeticIncrementErrorCode);
    exit(1);
  }

  printf("INCREMENT: About to do lcb_wait()...\n");
  lcb_wait(instance); 
  printf("INCREMENT: Back from lcb_wait()...\n");

} // end of blockingArithmeticIncrement2()
int main(void)
{
    struct lcb_create_st create_options;
    lcb_t instance;
    lcb_error_t err;

    memset(&create_options, 0, sizeof(create_options));
    create_options.v.v0.host = "ec2-204-236-172-232.us-west-1.compute.amazonaws.com:8091";
    create_options.v.v0.user = "******";
    create_options.v.v0.passwd = "password";
    create_options.v.v0.bucket = "default";

    err = lcb_create(&instance, &create_options);
    if (err != LCB_SUCCESS) {
        fprintf(stderr, "Failed to create libcouchbase instance: %s\n",
                lcb_strerror(NULL, err));
        return 1;
    }
    else {
        fprintf(stdout, "Successful in creating libCouchbase instance: %s\n");
    }
    if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
        fprintf(stderr, "Failed to initiate connect: %s\n",
                lcb_strerror(NULL, err));
        return 1;
    }
    else {
        fprintf(stdout, "Successful in initializing libCouchbase instance: %s\n");
    }

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

    lcb_arithmetic_cmd_t arithmetic;
    memset(&arithmetic, 0, sizeof(arithmetic));
    arithmetic.version = 0;
    arithmetic.v.v0.key = "036";
    arithmetic.v.v0.nkey = sizeof(arithmetic.v.v0.key);
    arithmetic.v.v0.create = 1;
    arithmetic.v.v0.delta = -10;
    arithmetic.v.v0.initial = 036;
    const lcb_arithmetic_cmd_t* const commands[1] = { &arithmetic };
    err = lcb_arithmetic(instance, NULL, 1, commands);
    if (err != LCB_SUCCESS) {
        fprintf(stderr, "Failed to incr %s\n",
            lcb_strerror(NULL, err));
        return 1;
    }
    else {
        fprintf(stdout, "Successful in incrementingthe keys and Values: %s\n");
    }

    lcb_wait(instance);

    lcb_destroy(instance);
    exit(EXIT_SUCCESS);
}
Ejemplo n.º 7
0
    static inline VALUE
cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
{
    struct cb_bucket_st *bucket = DATA_PTR(self);
    struct cb_context_st *ctx;
    VALUE rv, proc, exc;
    lcb_error_t err;
    struct cb_params_st params;

    if (!cb_bucket_connected_bang(bucket, sign > 0 ? cb_sym_increment : cb_sym_decrement)) {
        return Qnil;
    }

    memset(&params, 0, sizeof(struct cb_params_st));
    rb_scan_args(argc, argv, "0*&", &params.args, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    params.type = cb_cmd_arith;
    params.bucket = bucket;
    params.cmd.arith.sign = sign;
    cb_params_build(&params);
    ctx = cb_context_alloc_common(bucket, proc, params.cmd.arith.num);
    err = lcb_arithmetic(bucket->handle, (const void *)ctx,
            params.cmd.arith.num, params.cmd.arith.ptr);
    cb_params_destroy(&params);
    exc = cb_check_error(err, "failed to schedule arithmetic request", Qnil);
    if (exc != Qnil) {
        cb_context_free(ctx);
        rb_exc_raise(exc);
    }
    bucket->nbytes += params.npayload;
    if (bucket->async) {
        cb_maybe_do_loop(bucket);
        return Qnil;
    } else {
        if (ctx->nqueries > 0) {
            /* we have some operations pending */
            lcb_wait(bucket->handle);
        }
        exc = ctx->exception;
        rv = ctx->rv;
        cb_context_free(ctx);
        if (exc != Qnil) {
            rb_exc_raise(exc);
        }
        if (params.cmd.store.num > 1) {
            return rv;  /* return as a hash {key => cas, ...} */
        } else {
            VALUE vv = Qnil;
            rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
            return vv;
        }
        return rv;
    }
}
int couchbase_add(cachedb_con *connection,str *attr,int val,int expires,int *new_val)
{
	lcb_t instance;
	lcb_error_t oprc;
	lcb_arithmetic_cmd_t cmd;
	const lcb_arithmetic_cmd_t *commands[1];

	last_error = LCB_SUCCESS;
	instance = COUCHBASE_CON(connection);

	commands[0] = &cmd;
	memset(&cmd, 0, sizeof(cmd));
	cmd.v.v0.key = attr->s;
	cmd.v.v0.nkey = attr->len;
	cmd.v.v0.delta = val;
	cmd.v.v0.create = 1;
	cmd.v.v0.initial = val;
	cmd.v.v0.exptime = expires;
	oprc = lcb_arithmetic(instance, NULL, 1, commands);

	if (oprc != LCB_SUCCESS) {
		LM_ERR("Failed to send the arithmetic query - %s\n", lcb_strerror(instance, oprc));
		couchbase_conditional_reconnect(connection, oprc);
		return -2;
	}

	lcb_wait(instance);

	if (last_error != LCB_SUCCESS) {
		couchbase_conditional_reconnect(connection, last_error);
		return -1;
	}

	if (new_val)
		*new_val = arithmetic_res;

	return 1;
}
Ejemplo n.º 9
0
PHP_COUCHBASE_LOCAL
void php_couchbase_arithmetic_impl(INTERNAL_FUNCTION_PARAMETERS, char op, int oo) /* {{{ */
{
	char *key;
	time_t exp = {0};
	long klen = 0, offset = 1, expire = 0;
	long create = 0, initial = 0;
	php_couchbase_res *couchbase_res;
	int argflags = oo ? PHP_COUCHBASE_ARG_F_OO : PHP_COUCHBASE_ARG_F_FUNCTIONAL;

	PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags,
			"s|llll", &key, &klen, &offset, &create, &expire, &initial);

	{
		lcb_error_t retval;
		php_couchbase_ctx *ctx;
		long delta = (op == '+') ? offset : -offset;

		if (expire) {
			exp = pcbc_check_expiry(expire);
		}

		ctx = ecalloc(1, sizeof(php_couchbase_ctx));
		ctx->res = couchbase_res;
		ctx->rv = return_value;

		{
			lcb_arithmetic_cmd_t cmd;
			lcb_arithmetic_cmd_t *commands[] = { &cmd };
			memset(&cmd, 0, sizeof(cmd));
			cmd.v.v0.key = key;
			cmd.v.v0.nkey = klen;
			cmd.v.v0.create = create;
			cmd.v.v0.delta = delta;
			cmd.v.v0.initial = initial;
			cmd.v.v0.exptime = exp;

			retval = lcb_arithmetic(couchbase_res->handle, ctx, 1,
			                        (const lcb_arithmetic_cmd_t * const *)commands);
		}
		if (LCB_SUCCESS != retval) {
			efree(ctx);
			php_error_docref(NULL TSRMLS_CC, E_WARNING,
			                 "Failed to schedule rithmetic request: %s", lcb_strerror(couchbase_res->handle, retval));
			RETURN_FALSE;
		}

		couchbase_res->seqno += 1;
		pcbc_start_loop(couchbase_res);
		if (LCB_SUCCESS != ctx->res->rc) {
			// Just return false and don't print a warning when no key is present and create is false
			if (!(LCB_KEY_ENOENT == ctx->res->rc && create == 0)) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING,
				                 "Failed to %s value in server: %s", (op == '+') ? "increment" : "decrement", lcb_strerror(couchbase_res->handle, ctx->res->rc));
			}
			efree(ctx);
			RETURN_FALSE;
		}

		efree(ctx);
	}
}
Ejemplo n.º 10
0
PHP_COUCHBASE_LOCAL
void php_couchbase_arithmetic_impl(INTERNAL_FUNCTION_PARAMETERS, char op, int oo)
{
	char *key;
	time_t exp;
	long klen = 0;
	long offset = 1;
	long expire = 0;
	long create = 0;
	long initial = 0;
	php_couchbase_res *couchbase_res;
	lcb_arithmetic_cmd_t cmd;
	const lcb_arithmetic_cmd_t *const commands[] = { &cmd };
	lcb_error_t retval;
	struct arithmetic_cookie cookie;
	int argflags;
	long delta;
	lcb_t instance;

	argflags = oo ? PHP_COUCHBASE_ARG_F_OO : PHP_COUCHBASE_ARG_F_FUNCTIONAL;
	PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags,
							 "s|llll", &key, &klen, &offset, &create,
							 &expire, &initial);

	if (pcbc_check_expiry(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
						  expire, &exp) == -1) {
		/* Incorrect expiry time */
		return;
	}

	instance = couchbase_res->handle;
	memset(&cookie, 0, sizeof(cookie));
	delta = (op == '+') ? offset : -offset;

	memset(&cmd, 0, sizeof(cmd));
	cmd.v.v0.key = key;
	cmd.v.v0.nkey = klen;
	cmd.v.v0.create = create;
	cmd.v.v0.delta = delta;
	cmd.v.v0.initial = initial;
	cmd.v.v0.exptime = exp;

	lcb_behavior_set_syncmode(instance, LCB_SYNCHRONOUS);
	retval = lcb_arithmetic(instance, &cookie, 1, commands);
	lcb_behavior_set_syncmode(instance, LCB_ASYNCHRONOUS);

	if (retval == LCB_SUCCESS) {
		retval = cookie.error ;
	}
	couchbase_res->rc = retval;

	if (retval == LCB_SUCCESS) {
		ZVAL_LONG(return_value, cookie.value);
	} else {
		if (retval == LCB_KEY_ENOENT && create == 0) {
			/* The user told us to not create the key... */
			RETURN_FALSE;
		}

		couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
							   cb_lcb_exception,
							   "Failed to %s value in the server: %s",
							   (op == '+') ? "increment" : "decrement",
							   lcb_strerror(instance, retval));
	}
}
Ejemplo n.º 11
0
PyObject *
arithmetic_common(pycbc_Bucket *self,
                                   PyObject *args,
                                   PyObject *kwargs,
                                   int optype,
                                   int argopts)
{
    int rv;
    Py_ssize_t ncmds;
    struct arithmetic_common_vars global_params = { 0 };
    pycbc_seqtype_t seqtype;
    PyObject *all_initial_O = NULL;
    PyObject *all_ttl_O = NULL;
    PyObject *collection;
    lcb_error_t err;
    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;

    static char *kwlist[] = { "keys", "delta", "initial", "ttl", NULL };

    global_params.delta = 1;

    rv = PyArg_ParseTupleAndKeywords(args, kwargs, "O|LOO", kwlist,
                                     &collection,
                                     &global_params.delta,
                                     &all_initial_O,
                                     &all_ttl_O);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    rv = pycbc_get_ttl(all_ttl_O, &global_params.ttl, 1);
    if (rv < 0) {
        return NULL;
    }

    if (argopts & PYCBC_ARGOPT_MULTI) {
        rv = pycbc_oputil_check_sequence(collection, 1, &ncmds, &seqtype);
        if (rv < 0) {
            return NULL;
        }
    } else {
        ncmds = 1;
    }


    if (all_initial_O && PyNumber_Check(all_initial_O)) {
        global_params.create = 1;
        global_params.initial = pycbc_IntAsULL(all_initial_O);
    }

    rv = pycbc_common_vars_init(&cv,
                                self,
                                argopts,
                                ncmds,
                                sizeof(lcb_arithmetic_cmd_t),
                                0);

    if (argopts & PYCBC_ARGOPT_MULTI) {
        rv = pycbc_oputil_iter_multi(self,
                                     seqtype,
                                     collection,
                                     &cv,
                                     optype,
                                     handle_single_arith,
                                     &global_params);

    } else {
        rv = handle_single_arith(self,
                                 &cv, optype, collection, NULL, NULL, NULL, 0,
                                 &global_params);
    }

    if (rv < 0) {
        goto GT_DONE;
    }


    err = lcb_arithmetic(self->instance, cv.mres, ncmds, cv.cmdlist.arith);
    if (err != LCB_SUCCESS) {
        PYCBC_EXCTHROW_SCHED(err);
        goto GT_DONE;
    }

    if (-1 == pycbc_common_vars_wait(&cv, self)) {
        goto GT_DONE;
    }

    GT_DONE:
    pycbc_common_vars_finalize(&cv, self);
    return cv.ret;
}
Ejemplo n.º 12
0
    static inline VALUE
cb_bucket_arithmetic(int sign, int argc, VALUE *argv, VALUE self)
{
    struct bucket_st *bucket = DATA_PTR(self);
    struct context_st *ctx;
    VALUE args, rv, proc, exc;
    lcb_error_t err;
    struct params_st params;

    if (bucket->handle == NULL) {
        rb_raise(eConnectError, "closed connection");
    }
    rb_scan_args(argc, argv, "0*&", &args, &proc);
    if (!bucket->async && proc != Qnil) {
        rb_raise(rb_eArgError, "synchronous mode doesn't support callbacks");
    }
    memset(&params, 0, sizeof(struct params_st));
    params.type = cmd_arith;
    params.bucket = bucket;
    params.cmd.arith.sign = sign;
    cb_params_build(&params, RARRAY_LEN(args), args);
    ctx = xcalloc(1, sizeof(struct context_st));
    if (ctx == NULL) {
        rb_raise(eClientNoMemoryError, "failed to allocate memory for context");
    }
    rv = rb_hash_new();
    ctx->rv = &rv;
    ctx->bucket = bucket;
    ctx->proc = cb_gc_protect(bucket, proc);
    ctx->exception = Qnil;
    ctx->nqueries = params.cmd.arith.num;
    err = lcb_arithmetic(bucket->handle, (const void *)ctx,
            params.cmd.arith.num, params.cmd.arith.ptr);
    cb_params_destroy(&params);
    exc = cb_check_error(err, "failed to schedule arithmetic request", Qnil);
    if (exc != Qnil) {
        xfree(ctx);
        rb_exc_raise(exc);
    }
    bucket->nbytes += params.npayload;
    if (bucket->async) {
        maybe_do_loop(bucket);
        return Qnil;
    } else {
        if (ctx->nqueries > 0) {
            /* we have some operations pending */
            lcb_wait(bucket->handle);
        }
        exc = ctx->exception;
        xfree(ctx);
        if (exc != Qnil) {
            cb_gc_unprotect(bucket, exc);
            rb_exc_raise(exc);
        }
        if (params.cmd.store.num > 1) {
            return rv;  /* return as a hash {key => cas, ...} */
        } else {
            VALUE vv = Qnil;
            rb_hash_foreach(rv, cb_first_value_i, (VALUE)&vv);
            return vv;
        }
        return rv;
    }
}