void pycbc_callbacks_init(lcb_t instance) { lcb_set_store_callback(instance, store_callback); lcb_set_unlock_callback(instance, unlock_callback); lcb_set_get_callback(instance, get_callback); lcb_set_touch_callback(instance, touch_callback); lcb_set_arithmetic_callback(instance, arithmetic_callback); lcb_set_remove_callback(instance, delete_callback); lcb_set_stat_callback(instance, stat_callback); lcb_set_error_callback(instance, error_callback); lcb_set_http_complete_callback(instance, http_complete_callback); }
LCBMT_INTERNAL void lcbmt_wrap_callbacks(lcbmt_ctx_t *mt, lcb_t instance) { lcb_set_store_callback(instance, store_callback); lcb_set_get_callback(instance, get_callback); lcb_set_remove_callback(instance, remove_callback); lcb_set_arithmetic_callback(instance, arithmetic_callback); lcb_set_touch_callback(instance, touch_callback); lcb_set_unlock_callback(instance, unlock_callback); lcb_set_stat_callback(instance, stats_callback); lcb_set_durability_callback(instance, endure_callback); lcb_set_http_data_callback(instance, http_data_callback); lcb_set_http_complete_callback(instance, http_complete_callback); }
ERL_NIF_TERM cb_connect(ErlNifEnv* env, handle_t* handle, void* obj) { connect_args_t* args = (connect_args_t*)obj; lcb_error_t err; struct lcb_create_st create_options; struct lcb_create_io_ops_st io_opts; io_opts.version = 0; io_opts.v.v0.type = LCB_IO_OPS_DEFAULT; io_opts.v.v0.cookie = NULL; memset(&create_options, 0, sizeof(create_options)); err = lcb_create_io_ops(&create_options.v.v0.io, &io_opts); if (err != LCB_SUCCESS) { printf("failed create io ops\n"); fprintf(stderr, "Failed to create IO instance: %s\n", lcb_strerror(NULL, err)); return return_lcb_error(env, err); } create_options.v.v0.host = args->host; create_options.v.v0.user = args->user; create_options.v.v0.bucket = args->bucket; create_options.v.v0.passwd = args->pass; err = lcb_create(&(handle->instance), &create_options); free(args->host); free(args->user); free(args->pass); free(args->bucket); if (err != LCB_SUCCESS) { return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, lcb_strerror(NULL, err), ERL_NIF_LATIN1)); } (void)lcb_set_get_callback(handle->instance, get_callback); (void)lcb_set_store_callback(handle->instance, store_callback); (void)lcb_set_unlock_callback(handle->instance, unlock_callback); (void)lcb_set_touch_callback(handle->instance, touch_callback); (void)lcb_set_arithmetic_callback(handle->instance, arithmetic_callback); (void)lcb_set_remove_callback(handle->instance, remove_callback); (void)lcb_set_http_complete_callback(handle->instance, http_callback); err = lcb_connect(handle->instance); if (err != LCB_SUCCESS) { return return_lcb_error(env, err); } err = lcb_wait(handle->instance); if(err != LCB_SUCCESS) { return return_lcb_error(env, err); } #ifdef LCB_CNTL_DETAILED_ERRCODES int val = 1; err = lcb_cntl(handle->instance, LCB_CNTL_SET, LCB_CNTL_DETAILED_ERRCODES, &val); if(err != LCB_SUCCESS) { return return_lcb_error(env, err); } #endif return enif_make_atom(env, "ok"); }
// Main int main(int argc, char* argv[]) { printf("Welcome.\n"); // Do this once srand(time(NULL)); // initializing struct lcb_create_st cropts = { 0 }; cropts.version = 3; cropts.v.v3.connstr = "couchbase://localhost/default"; // cropts.v.v3.connstr = "couchbase://192.168.38.101/default"; lcb_error_t create_err; lcb_t instance; create_err = lcb_create(&instance, &cropts); if (create_err != LCB_SUCCESS) { printf("Couldn't create instance!\n"); exit(1); } // connecting lcb_connect(instance); lcb_wait(instance); lcb_error_t bootstrap_status_err; if ( (bootstrap_status_err = lcb_get_bootstrap_status(instance)) != LCB_SUCCESS ) { printf("Couldn't bootstrap!\n"); exit(1); } // installing callbacks lcb_set_store_callback(instance, storage_callback); lcb_set_get_callback(instance, get_callback); lcb_set_arithmetic_callback(instance, arithmetic_callback); lcb_set_touch_callback(instance, touch_callback); lcb_set_remove_callback(instance, remove_callback); // Main part of the program int numTimesToRun = 10; // specify how many times to iterate int useARandomKey = 1; // specify whether to use a random or sequential key char keyNameBuffer[100]; int i = 0; for (i = 0; i < numTimesToRun; i++) { if (useARandomKey == 0) { // Do NOT use a random key sprintf(keyNameBuffer, "NonRandomKey%d", i); } else { // Use a random key, generate a new one for each iteration of the loop int randomNumber = rand(); sprintf(keyNameBuffer, "randomKey%d", randomNumber); } printf("#### Iteration: %5d Key: %10s\n", i, keyNameBuffer); // Create-Increment blockingArithmeticIncrement2(instance, keyNameBuffer); // Make sure its there blockingGet(instance, keyNameBuffer); // Delete blockingRemove(instance, keyNameBuffer); // Sleep 60 printf("About to sleep...\n"); sleep(1); printf("Done with sleep...\n"); // Touch, should fail blockingTouch2(instance, 60, keyNameBuffer); // Increment blockingArithmeticIncrement2(instance, keyNameBuffer); // Touch blockingTouch2(instance, 60, keyNameBuffer); printf("##### touches that worked: %d touches that failed %d\n", touchesWorked, touchesFailed); } // loop for numTimesToRun printf("Almost done. Calling lcb_destroy()\n"); lcb_destroy(instance); printf("Goodbye\n"); return 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); } }
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); }
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); }