int couchbase_remove(cachedb_con *connection,str *attr) { lcb_t instance; lcb_error_t oprc; lcb_remove_cmd_t cmd; const lcb_remove_cmd_t *commands[1]; struct timeval start; start_expire_timer(start,couch_exec_threshold); instance = COUCHBASE_CON(connection); commands[0] = &cmd; memset(&cmd, 0, sizeof(cmd)); cmd.v.v0.key = attr->s; cmd.v.v0.nkey = attr->len; oprc = lcb_remove(instance, NULL, 1, commands); if (oprc != LCB_SUCCESS) { if (oprc == LCB_KEY_ENOENT) { stop_expire_timer(start,couch_exec_threshold, "cachedb_couchbase remove",attr->s,attr->len,0); return -1; } LM_ERR("Failed to send the remove query - %s\n", lcb_strerror(instance, oprc)); if (couchbase_conditional_reconnect(connection, oprc) != 1) { stop_expire_timer(start,couch_exec_threshold, "cachedb_couchbase remove",attr->s,attr->len,0); return -2; }; instance = COUCHBASE_CON(connection); oprc = lcb_remove(instance, NULL, 1, commands); if (oprc != LCB_SUCCESS) { if (oprc == LCB_KEY_ENOENT) { LM_ERR("Remove command successfully retried\n"); stop_expire_timer(start,couch_exec_threshold, "cachedb_couchbase remove",attr->s,attr->len,0); return -1; } LM_ERR("Remove command retry failed - %s\n", lcb_strerror(instance, oprc)); stop_expire_timer(start,couch_exec_threshold, "cachedb_couchbase remove",attr->s,attr->len,0); return -2; } LM_ERR("Remove command successfully retried\n"); } LM_DBG("Succesfully removed\n"); stop_expire_timer(start,couch_exec_threshold, "cachedb_couchbase remove",attr->s,attr->len,0); return 1; }
ERL_NIF_TERM cb_remove(ErlNifEnv* env, handle_t* handle, void* obj) { remove_args_t* args = (remove_args_t*)obj; struct libcouchbase_callback cb; lcb_error_t ret; //for checking responses lcb_remove_cmd_t remove; const lcb_remove_cmd_t* commands[1]; commands[0] = &remove; memset(&remove, 0, sizeof(remove)); remove.v.v0.key = args->key; remove.v.v0.nkey = args->nkey; remove.v.v0.cas = args->cas; ret = lcb_remove(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 A_OK(env); }
static void blockingRemove(lcb_t instance, char*keyName) { int keyLength = strlen(keyName); lcb_error_t removeErrorCode = 0; lcb_remove_cmd_t *removeCommand = calloc(1,sizeof(*removeCommand)); removeCommand->version = 0; removeCommand->v.v0.key = keyName; removeCommand->v.v0.nkey = keyLength; removeCommand->v.v0.cas = 0; const lcb_remove_cmd_t* removeCommands[] = { removeCommand }; removeErrorCode = lcb_remove(instance, NULL, 1, removeCommands); if (removeErrorCode != LCB_SUCCESS) { printf("Couldn't schedule remove operation!\n"); printf("lcb_remove errorCode is 0x%.8X \n", removeErrorCode); exit(1); } printf("REMOVE: About to do lcb_wait()...\n"); lcb_wait(instance); printf("REMOVE: Back from lcb_wait()...\n"); }
/* * Name: couchdb_delete * Input Args: * handle - handle to the lcb instance * key - key as in key-value pair * lock - this is the place holder for key specific R/W lock. Right * now, we are using a global database lock for synchronization * * Description: deletes the entry referred by the given key */ int couchdb_delete(uint64_t key) { char *db_key; size_t key_size; lcb_error_t ret; int lock_result; lcb_remove_cmd_t item; const lcb_remove_cmd_t *const del_items[] = { &item }; memset(&item, 0, sizeof(lcb_remove_cmd_t)); db_key = (char *) malloc(MAX_KEY_SIZE); if (NULL == db_key) { syslog(LOG_ERR, "%s: Unable to allocate memory for db_key \n", __FUNCTION__); return -ENOMEM; } sprintf(db_key,"%"PRId64"", key); key_size = strlen(db_key); lock_result = pthread_rwlock_wrlock(&db_rwlock); if (lock_result != 0) { syslog(LOG_ERR, "%s: Unable to obtain write lock. Error = %d\n", __FUNCTION__, errno); return -errno; } item.v.v0.key = db_key; item.v.v0.nkey = key_size; ret = lcb_remove(couchdb_handle, NULL, 1, del_items); if (ret != LCB_SUCCESS) { syslog(LOG_ERR, "%s: lcb_remove failed with error %s\n", __FUNCTION__, lcb_strerror(couchdb_handle, ret)); return -ret; } /* Block the thread till this operation completes */ lcb_wait(couchdb_handle); pthread_rwlock_unlock(&db_rwlock); return (1); }
int couchbase_remove(cachedb_con *connection,str *attr) { lcb_t instance; lcb_error_t oprc; lcb_remove_cmd_t cmd; const lcb_remove_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; oprc = lcb_remove(instance, NULL, 1, commands); if (oprc != LCB_SUCCESS) { LM_ERR("Failed to send the remove query - %s\n", lcb_strerror(instance, oprc)); couchbase_conditional_reconnect(connection, oprc); return -2; } lcb_wait(instance); if (last_error != LCB_SUCCESS) { /* Key not present, record does not exist */ if (last_error == LCB_KEY_ENOENT) { return -1; } couchbase_conditional_reconnect(connection, last_error); return -2; } LM_DBG("Succesfully removed\n"); return 1; }
static lcb_error_t do_remove(lcb_t instance, const void *key, uint16_t klen, lcb_cas_t *cas) { lcb_remove_cmd_t cmd; const lcb_remove_cmd_t *const commands[] = { &cmd }; struct remove_cookie rmc; lcb_error_t retval; memset(&cmd, 0, sizeof(cmd)); memset(&rmc, 0, sizeof(rmc)); cmd.v.v0.key = key; cmd.v.v0.nkey = klen; cmd.v.v0.cas = *cas; lcb_behavior_set_syncmode(instance, LCB_SYNCHRONOUS); retval = lcb_remove(instance, &rmc, 1, commands); lcb_behavior_set_syncmode(instance, LCB_ASYNCHRONOUS); if (retval == LCB_SUCCESS && rmc.error == LCB_SUCCESS) { *cas = rmc.cas; } return (retval == LCB_SUCCESS) ? rmc.error : retval; }
ngx_int_t ngx_lcb_process(ngx_http_request_t *r) { lcb_error_t err = LCB_NOT_SUPPORTED; ngx_http_variable_value_t *vv; ngx_str_t key, val; enum ngx_lcb_cmd opcode; ngx_http_core_loc_conf_t *clcf; ngx_lcb_connection_t *conn; lcb_cas_t cas = 0; lcb_uint32_t flags = 0, exptime = 0; ngx_int_t need_free_value = 0; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); conn = ngx_http_get_couchbase_connection(clcf->name); if (conn == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "couchbase: connection not found: \"%V\"", &clcf->name); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* setup command: use variable or fallback to HTTP method */ vv = ngx_http_get_indexed_variable(r, ngx_lcb_cmd_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (vv->not_found || vv->len == 0) { if (r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD)) { opcode = ngx_lcb_cmd_get; } else if (r->method == NGX_HTTP_POST) { opcode = ngx_lcb_cmd_add; } else if (r->method == NGX_HTTP_PUT) { opcode = ngx_lcb_cmd_set; } else if (r->method == NGX_HTTP_DELETE) { opcode = ngx_lcb_cmd_delete; } else { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_memc: $memc_cmd variable requires explicit " "assignment for HTTP request method %V", &r->method_name); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_HTTP_BAD_REQUEST; } } else { if (ngx_strncmp(vv->data, "get", 3) == 0) { opcode = ngx_lcb_cmd_get; } else if (ngx_strncmp(vv->data, "add", 3) == 0) { opcode = ngx_lcb_cmd_add; } else if (ngx_strncmp(vv->data, "replace", 7) == 0) { opcode = ngx_lcb_cmd_replace; } else if (ngx_strncmp(vv->data, "set", 3) == 0) { opcode = ngx_lcb_cmd_set; } else if (ngx_strncmp(vv->data, "append", 6) == 0) { opcode = ngx_lcb_cmd_append; } else if (ngx_strncmp(vv->data, "prepend", 7) == 0) { opcode = ngx_lcb_cmd_prepend; } else if (ngx_strncmp(vv->data, "delete", 6) == 0) { opcode = ngx_lcb_cmd_delete; } else { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "ngx_memc: unknown $couchbase_cmd \"%v\"", vv); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_HTTP_BAD_REQUEST; } } /* setup key: use variable or fallback to URI */ vv = ngx_http_get_indexed_variable(r, ngx_lcb_key_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (vv->not_found || vv->len == 0) { size_t loc_len; loc_len = r->valid_location ? clcf->name.len : 0; key.data = r->uri.data + loc_len; key.len = r->uri.len - loc_len; } else { u_char *dst, *src; key.data = ngx_palloc(r->pool, vv->len); if (key.data == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } dst = key.data; src = vv->data; ngx_unescape_uri(&dst, &src, vv->len, 0); *dst = 0; key.len = dst - key.data; } /* setup value: use variable or fallback to HTTP body */ ngx_str_null(&val); if (opcode >= ngx_lcb_cmd_add && opcode <= ngx_lcb_cmd_prepend) { vv = ngx_http_get_indexed_variable(r, ngx_lcb_val_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (vv->not_found || vv->len == 0) { if (r->request_body == NULL || r->request_body->bufs == NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "neither the \"$couchbase_value\" variable " "nor the request body is available"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_HTTP_BAD_REQUEST; } else { /* copy body to the buffer */ ngx_chain_t *cl; u_char *p; val.len = 0; for (cl = r->request_body->bufs; cl; cl = cl->next) { val.len += ngx_buf_size(cl->buf); } p = val.data = ngx_palloc(r->pool, val.len); if (p == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } for (cl = r->request_body->bufs; cl; cl = cl->next) { p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos); } vv = NULL; } } else { u_char *dst, *src; val.data = ngx_palloc(r->pool, vv->len); if (val.data == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } need_free_value = 1; dst = val.data; src = vv->data; ngx_unescape_uri(&dst, &src, vv->len, 0); *dst = 0; val.len = dst - val.data; } } /* setup CAS value */ vv = ngx_http_get_indexed_variable(r, ngx_lcb_cas_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (!vv->not_found && vv->len > 0) { if (ngx_lcb_atocas(vv->data, vv->len, &cas) != NGX_OK) { ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_HTTP_BAD_REQUEST; } } /* setup flags value */ vv = ngx_http_get_indexed_variable(r, ngx_lcb_flags_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (!vv->not_found && vv->len > 0) { flags = ngx_atoi(vv->data, vv->len); } /* setup expiration value */ vv = ngx_http_get_indexed_variable(r, ngx_lcb_exptime_idx); if (vv == NULL) { ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (!vv->not_found && vv->len > 0) { exptime = ngx_atoi(vv->data, vv->len); } switch (opcode) { case ngx_lcb_cmd_get: { lcb_get_cmd_t cmd; const lcb_get_cmd_t *commands[1]; commands[0] = &cmd; memset(&cmd, 0, sizeof(cmd)); cmd.v.v0.key = key.data; cmd.v.v0.nkey = key.len; cmd.v.v0.exptime = exptime; err = lcb_get(conn->lcb, r, 1, commands); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "couchbase(%p): get request \"%*s\"", (void *)conn->lcb, cmd.v.v0.nkey, cmd.v.v0.key); } break; case ngx_lcb_cmd_add: case ngx_lcb_cmd_replace: case ngx_lcb_cmd_set: case ngx_lcb_cmd_append: case ngx_lcb_cmd_prepend: { lcb_store_cmd_t cmd; const lcb_store_cmd_t *commands[1]; commands[0] = &cmd; memset(&cmd, 0, sizeof(cmd)); cmd.v.v0.operation = opcode; cmd.v.v0.key = key.data; cmd.v.v0.nkey = key.len; cmd.v.v0.bytes = val.data; cmd.v.v0.nbytes = val.len; cmd.v.v0.cas = cas; cmd.v.v0.flags = flags; cmd.v.v0.exptime = exptime; err = lcb_store(conn->lcb, r, 1, commands); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "couchbase(%p): store request \"%*s\", operation: 0x%02xd", (void *)conn->lcb, cmd.v.v0.nkey, cmd.v.v0.key, cmd.v.v0.operation); } break; case ngx_lcb_cmd_delete: { lcb_remove_cmd_t cmd; const lcb_remove_cmd_t *commands[1]; commands[0] = &cmd; memset(&cmd, 0, sizeof(cmd)); cmd.v.v0.key = key.data; cmd.v.v0.nkey = key.len; err = lcb_remove(conn->lcb, r, 1, commands); ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "couchbase(%p): remove request \"%*s\"", (void *)conn->lcb, cmd.v.v0.nkey, cmd.v.v0.key); } break; } if (need_free_value) { ngx_pfree(r->pool, val.data); } if (err != LCB_SUCCESS) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "couchbase: failed to schedule couchbase request: %s", lcb_strerror(conn->lcb, err)); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); return NGX_ERROR; } return NGX_OK; }
static PyObject * keyop_common(pycbc_Connection *self, PyObject *args, PyObject *kwargs, int optype, int argopts) { int rv; int ii; Py_ssize_t ncmds = 0; pycbc_seqtype_t seqtype; PyObject *casobj = NULL; PyObject *ret = NULL; PyObject *is_quiet = NULL; PyObject *kobj = NULL; pycbc_MultiResult *mres = NULL; lcb_error_t err; struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT; static char *kwlist[] = { "keys", "cas", "quiet", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO", kwlist, &kobj, &casobj, &is_quiet); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (argopts & PYCBC_ARGOPT_MULTI) { rv = pycbc_oputil_check_sequence(kobj, 1, &ncmds, &seqtype); if (rv < 0) { return NULL; } if (casobj && PyObject_IsTrue(casobj)) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Can't pass CAS for multiple keys"); } } else { ncmds = 1; } rv = pycbc_common_vars_init(&cv, ncmds, sizeof(lcb_remove_cmd_t), 0); if (rv < 0) { return NULL; } if (argopts & PYCBC_ARGOPT_MULTI) { Py_ssize_t dictpos = 0; PyObject *curseq, *iter = NULL; curseq = pycbc_oputil_iter_prepare(seqtype, kobj, &iter, &dictpos); if (!curseq) { goto GT_DONE; } for (ii = 0; ii < ncmds; ii++) { PyObject *curkey = NULL, *curvalue = NULL; rv = pycbc_oputil_sequence_next(seqtype, curseq, &dictpos, ii, &curkey, &curvalue); if (rv < 0) { goto GT_ITER_DONE; } rv = handle_single_keyop(self, curkey, curvalue, ii, optype, &cv); Py_XDECREF(curkey); Py_XDECREF(curvalue); if (rv < 0) { goto GT_ITER_DONE; } } GT_ITER_DONE: Py_XDECREF(iter); if (rv < 0) { goto GT_DONE; } } else { rv = handle_single_keyop(self, kobj, casobj, 0, optype, &cv); if (rv < 0) { goto GT_DONE; } } mres = (pycbc_MultiResult*)pycbc_multiresult_new(self); if (optype == PYCBC_CMD_DELETE) { if (pycbc_maybe_set_quiet(mres, is_quiet) == -1) { goto GT_DONE; } err = lcb_remove(self->instance, mres, ncmds, cv.cmdlist.remove); } else { err = lcb_unlock(self->instance, mres, ncmds, cv.cmdlist.unlock); } if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_WAIT(err); goto GT_DONE; } if (!pycbc_multiresult_maybe_raise(mres)) { ret = (PyObject*)mres; } GT_DONE: pycbc_common_vars_free(&cv); ret = pycbc_make_retval(argopts, &ret, &mres); Py_XDECREF(mres); return ret; }