// Doing a touch will set the expiration time of the item
// http://docs.couchbase.com/sdk-api/couchbase-c-client-2.4.6/group__lcb-touch.html
void blockingTouch(lcb_t instance, int expTimeSeconds, char *keyName) {

  int keyLength = strlen(keyName);

  lcb_error_t      touchErrorCode = 0;
  lcb_touch_cmd_t *touchCommand   = calloc(1, sizeof(*touchCommand));

  touchCommand->v.v0.key     = keyName;
  touchCommand->v.v0.nkey    = keyLength;
  touchCommand->v.v0.exptime = expTimeSeconds; 
  touchCommand->v.v0.lock    = 0; 

  const lcb_touch_cmd_t *touchCommandList[] = { touchCommand };

  touchErrorCode = lcb_touch(instance, NULL, 1, touchCommandList);
  if (touchErrorCode != LCB_SUCCESS) {
    printf("Couldn't schedule touch operation!\n");
    printf("lcb_touch errorCode is 0x%.8X \n", touchErrorCode);
    exit(1);
  }

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

} // end of blockingTouch()
Esempio n. 2
0
File: cb.c Progetto: muut/cberl
ERL_NIF_TERM cb_mtouch(ErlNifEnv* env, handle_t* handle, void* obj)
{
    mtouch_args_t* args = (mtouch_args_t*)obj;

    struct libcouchbase_callback_m cb;
    int i = 0;
    lcb_error_t ret;

    ERL_NIF_TERM* results;
    ERL_NIF_TERM returnValue;

    ErlNifBinary key_binary;

    cb.currKey = 0;
    cb.ret = malloc(sizeof(struct libcouchbase_callback*) * args->numkeys);

    const lcb_touch_cmd_t* commands[args->numkeys];
    i = 0;
    for (; i < args->numkeys; i++) {
      lcb_touch_cmd_t* touch = calloc(1, sizeof(*touch));
      touch->version = 0;
      touch->v.v0.key = args->keys[i];
      touch->v.v0.nkey = args->nkeys[i];
      touch->v.v0.exptime = args->exp[i];
      commands[i] = touch;
    }

    ret = lcb_touch(handle->instance, &cb, args->numkeys, commands);

    if (ret != LCB_SUCCESS) {
        return return_lcb_error(env, ret);
    }
    lcb_wait(handle->instance);

    results = malloc(sizeof(ERL_NIF_TERM) * args->numkeys);
    i = 0;
    for(; i < args->numkeys; i++) {
        enif_alloc_binary(cb.ret[i]->nkey, &key_binary);
        memcpy(key_binary.data, cb.ret[i]->key, cb.ret[i]->nkey);
        ERL_NIF_TERM key = enif_make_binary(env, &key_binary);
        if (cb.ret[i]->error == LCB_SUCCESS) {
            results[i] = enif_make_tuple2(env,
                    key,
                    A_OK(env));
        } else {
            results[i] = enif_make_tuple2(env,
                    key,
                    return_lcb_error(env, cb.ret[i]->error));
        }
        free(cb.ret[i]->key);
        free(cb.ret[i]);
        free(args->keys[i]);
        free((lcb_touch_cmd_t*) commands[i]);
    }
    returnValue = enif_make_list_from_array(env, results, args->numkeys);

    free(results);
    free(cb.ret);
    free(args->keys);
    free(args->exp);
    free(args->nkeys);

    return enif_make_tuple2(env, A_OK(env), returnValue);
}
Esempio n. 3
0
PHP_COUCHBASE_LOCAL
void php_couchbase_touch_multi_impl(INTERNAL_FUNCTION_PARAMETERS, int oo)
{
	int argflags;
	int idx = 0;
	int ii;
	lcb_error_t retval;
	lcb_t instance;
	lcb_time_t exp = 0;
	lcb_touch_cmd_t **commands;
	lcb_touch_cmd_t *cmd;
	long expiry;
	php_couchbase_res *couchbase_res;
	struct multi_touch_cookie cookie;
	zval **ppzval;
	zval *arr_keys;

	/* parameter handling and return_value setup: */
	if (oo) {
		argflags = PHP_COUCHBASE_ARG_F_OO;
	} else {
		argflags = PHP_COUCHBASE_ARG_F_FUNCTIONAL;
	}

	PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags, "al", &arr_keys, &expiry);

	instance = couchbase_res->handle;
	memset(&cookie, 0, sizeof(cookie));
	cookie.nkeys = zend_hash_num_elements(Z_ARRVAL_P(arr_keys));
	cookie.keys = ecalloc(cookie.nkeys, sizeof(struct touch_cookie));

	for (ii = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(arr_keys));
			zend_hash_has_more_elements(Z_ARRVAL_P(arr_keys)) == SUCCESS;
			zend_hash_move_forward(Z_ARRVAL_P(arr_keys)), ii++) {
		if (zend_hash_get_current_data(Z_ARRVAL_P(arr_keys),
									   (void **)&ppzval) == FAILURE) {
			continue;
		}

		if (IS_ARRAY != Z_TYPE_PP(ppzval)) {
			convert_to_string_ex(ppzval);
		}

		if (!Z_STRLEN_PP(ppzval)) {
			continue;
		}

		if (couchbase_res->prefix_key_len) {
			cookie.keys[idx].nkey = spprintf(&(cookie.keys[idx].key), 0,
											 "%s_%s",
											 couchbase_res->prefix_key,
											 Z_STRVAL_PP(ppzval));
		} else {
			cookie.keys[idx].key = Z_STRVAL_PP(ppzval);
			cookie.keys[idx].nkey = Z_STRLEN_PP(ppzval);
		}
		++idx;
	}

	if (idx == 0) {
		efree(cookie.keys);
		couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
							   cb_illegal_key_exception,
							   "No keys specified");
		return;
	}

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

	cmd = ecalloc(idx, sizeof(lcb_touch_cmd_t));
	commands = ecalloc(idx, sizeof(lcb_touch_cmd_t *));
	for (ii = 0; ii < idx; ++ii) {
		cmd[ii].v.v0.key = cookie.keys[ii].key;
		cmd[ii].v.v0.nkey = cookie.keys[ii].nkey;
		cmd[ii].v.v0.exptime = exp;
		commands[ii] = cmd + ii;
	}

	lcb_set_touch_callback(instance, multi_touch_callback);
	lcb_behavior_set_syncmode(instance, LCB_SYNCHRONOUS);
	retval = lcb_touch(instance, &cookie, idx,
					   (const lcb_touch_cmd_t * const *)commands);
	lcb_behavior_set_syncmode(instance, LCB_ASYNCHRONOUS);

	if (retval == LCB_SUCCESS) {
		retval = cookie.error;
	}

	couchbase_res->rc = retval;
	if (retval == LCB_SUCCESS) {
		/* Time to build up the array with the keys we found etc */
		array_init(return_value);
		for (ii = 0; ii < idx; ++ii) {
			char *k = cookie.keys[ii].key;
			if (cookie.keys[ii].error == LCB_SUCCESS) {
				char cas[80];
				snprintf(cas, sizeof(cas), "%llu",
						 (unsigned long long)cookie.keys[ii].cas);
				add_assoc_string(return_value, k, cas, 1);
			} else {
				add_assoc_bool(return_value, k, (zend_bool)0);
			}
		}
	} else {
		couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
							   cb_lcb_exception,
							   "Failed to touch key: %s",
							   lcb_strerror(instance, retval));
	}

	/* Release allocated memory */
	efree(cmd);
	efree(commands);
	if (couchbase_res->prefix_key_len) {
		for (ii = 0; ii < idx; ++ii) {
			efree(cookie.keys[ii].key);
		}
	}
	efree(cookie.keys);
}
Esempio n. 4
0
PHP_COUCHBASE_LOCAL
void php_couchbase_touch_impl(INTERNAL_FUNCTION_PARAMETERS, int oo)
{
	struct touch_cookie cookie;
	char *key = NULL;
	long nkey = 0;
	lcb_time_t exp = 0;
	long expiry;
	php_couchbase_res *couchbase_res;
	int argflags;
	lcb_t instance;
	lcb_error_t retval;
	lcb_touch_cmd_t cmd;
	const lcb_touch_cmd_t *const commands[] = { &cmd };

	/* parameter handling and return_value setup: */
	if (oo) {
		argflags = PHP_COUCHBASE_ARG_F_OO;
	} else {
		argflags = PHP_COUCHBASE_ARG_F_FUNCTIONAL;
	}

	PHP_COUCHBASE_GET_PARAMS(couchbase_res, argflags, "sl", &key, &nkey, &expiry);

	if (!nkey) {
		couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
							   cb_illegal_key_exception,
							   "No key specified: Empty key");
		return;
	}

	if (couchbase_res->prefix_key_len) {
		nkey = spprintf(&key, 0, "%s_%s", couchbase_res->prefix_key, key);
	}

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

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

	instance = couchbase_res->handle;
	cookie.error = LCB_ERROR;
	lcb_set_touch_callback(instance, single_touch_callback);
	lcb_behavior_set_syncmode(instance, LCB_SYNCHRONOUS);
	retval = lcb_touch(instance, &cookie, 1, commands);
	lcb_behavior_set_syncmode(instance, LCB_ASYNCHRONOUS);

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

	if (couchbase_res->prefix_key_len) {
		efree(key);
	}

	if (retval != LCB_SUCCESS) {
		couchbase_report_error(INTERNAL_FUNCTION_PARAM_PASSTHRU, oo,
							   cb_lcb_exception,
							   "Failed to touch key: %s",
							   lcb_strerror(instance, retval));
		return;
	} else {
		Z_TYPE_P(return_value) = IS_STRING;
		Z_STRLEN_P(return_value) = spprintf(&(Z_STRVAL_P(return_value)), 0,
											"%llu", cookie.cas);
	}
}
Esempio n. 5
0
static void test_touch1(void)
{
    lcb_error_t err;
    struct rvbuf rv;
    char *key = "fooX", *val = "bar";
    lcb_size_t nkey = strlen(key), nval = strlen(val);
    char **keys;
    lcb_size_t *nkeys, ii;
    lcb_time_t *ttls;
    lcb_store_cmd_t storecmd;
    const lcb_store_cmd_t *storecmds[] = { &storecmd };
    lcb_touch_cmd_t *touchcmds[26];

    (void)lcb_set_store_callback(session, store_callback);
    (void)lcb_set_touch_callback(session, touch_callback);

    keys = malloc(26 * sizeof(char *));
    nkeys = malloc(26 * sizeof(lcb_size_t));
    ttls = malloc(26 * sizeof(lcb_time_t));
    if (keys == NULL || nkeys == NULL || ttls == NULL) {
        err_exit("Failed to allocate memory for keys");
    }
    for (ii = 0; ii < 26; ii++) {
        nkeys[ii] = nkey;
        keys[ii] = strdup(key);
        ttls[ii] = 1;

        if (keys[ii] == NULL) {
            err_exit("Failed to allocate memory for key");
        }

        keys[ii][3] = (char)(ii + 'a');
        memset(&storecmd, 0, sizeof(storecmd));
        storecmd.v.v0.key = keys[ii];
        storecmd.v.v0.nkey = nkey;
        storecmd.v.v0.bytes = val;
        storecmd.v.v0.nbytes = nval;
        storecmd.v.v0.operation = LCB_SET;
        err = lcb_store(session, &rv, 1, storecmds);
        lcb_assert(err == LCB_SUCCESS);
        io->v.v0.run_event_loop(io);
        lcb_assert(rv.error == LCB_SUCCESS);
        memset(&rv, 0, sizeof(rv));

        touchcmds[ii] = calloc(1, sizeof(lcb_touch_cmd_t));
        if (touchcmds[ii] == NULL) {
            err_exit("Failed to allocate memory for touch command");
        }
        touchcmds[ii]->v.v0.key = keys[ii];
        touchcmds[ii]->v.v0.nkey = nkey;
    }

    rv.counter = 26;
    err = lcb_touch(session, &rv, 26, (const lcb_touch_cmd_t * const *)touchcmds);
    lcb_assert(err == LCB_SUCCESS);
    io->v.v0.run_event_loop(io);
    lcb_assert(rv.error == LCB_SUCCESS);
    for (ii = 0; ii < 26; ii++) {
        free(keys[ii]);
        free(touchcmds[ii]);
    }
    free(keys);
    free(ttls);
    free(nkeys);
}