Пример #1
0
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;
}
Пример #2
0
Файл: cb.c Проект: muut/cberl
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");

}
Пример #4
0
/*
 * 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;
}
Пример #6
0
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;
}
Пример #8
0
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;
}