static PyObject * observe_common(pycbc_Connection *self, PyObject *args, PyObject *kwargs, int argopts) { int rv; int ii; Py_ssize_t ncmds; PyObject *kobj = NULL; pycbc_seqtype_t seqtype; lcb_error_t err; int master_only = 0; PyObject *master_only_O = NULL; struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT; static char *kwlist[] = { "keys", "master_only", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &kobj, &master_only_O); 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; } } else { ncmds = 1; } master_only = master_only_O && PyObject_IsTrue(master_only_O); rv = pycbc_common_vars_init(&cv, self, argopts, ncmds, sizeof(lcb_observe_cmd_t), 0); if (rv < 0) { return NULL; } if (argopts & PYCBC_ARGOPT_MULTI) { Py_ssize_t dictpos; 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_observe(self, curkey, ii, master_only, &cv); GT_ITER_DONE: Py_XDECREF(curkey); Py_XDECREF(curvalue); if (rv < 0) { goto GT_DONE; } } } else { rv = handle_single_observe(self, kobj, 0, master_only, &cv); if (rv < 0) { goto GT_DONE; } } err = lcb_observe(self->instance, cv.mres, ncmds, cv.cmdlist.obs); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } cv.is_seqcmd = 1; if (-1 == pycbc_common_vars_wait(&cv, self)) { goto GT_DONE; } GT_DONE: pycbc_common_vars_finalize(&cv, self); return cv.ret; }
/** * This is called during each iteration of delete/unlock */ static int handle_single_keyop(pycbc_Bucket *self, struct pycbc_common_vars *cv, int optype, PyObject *curkey, PyObject *curval, PyObject *options, pycbc_Item *item, void *arg) { int rv; char *key; size_t nkey; lcb_U64 cas = 0; lcb_error_t err; union { lcb_CMDBASE base; lcb_CMDREMOVE rm; lcb_CMDUNLOCK unl; lcb_CMDENDURE endure; } ucmd; (void)options; (void)arg; memset(&ucmd, 0, sizeof ucmd); if ( (optype == PYCBC_CMD_UNLOCK || optype == PYCBC_CMD_ENDURE) && PYCBC_OPRES_CHECK(curkey)) { curval = curkey; curkey = ((pycbc_OperationResult*)curkey)->key; } rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv == -1) { return -1; } if (!nkey) { PYCBC_EXCTHROW_EMPTYKEY(); rv = -1; goto GT_DONE; } if (item) { cas = item->cas; } else if (curval) { if (PyDict_Check(curval)) { PyObject *cas_o = PyDict_GetItemString(curval, "cas"); if (!cas_o) { PyErr_Clear(); } cas = pycbc_IntAsULL(cas_o); } else if (PYCBC_OPRES_CHECK(curval)) { /* If we're passed a Result object, just extract its CAS */ cas = ((pycbc_OperationResult*)curval)->cas; } else if (PyNumber_Check(curval)) { cas = pycbc_IntAsULL(curval); } if (cas == (lcb_uint64_t)-1 && PyErr_Occurred()) { PyErr_Clear(); PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Invalid CAS specified"); return -1; } } LCB_CMD_SET_KEY(&ucmd.base, key, nkey); ucmd.base.cas = cas; if (optype == PYCBC_CMD_UNLOCK) { if (!cas) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "CAS must be specified for unlock"); return -1; } err = lcb_unlock3(self->instance, cv->mres, &ucmd.unl); } else if (optype == PYCBC_CMD_ENDURE) { err = cv->mctx->addcmd(cv->mctx, &ucmd.base); } else { err = lcb_remove3(self->instance, cv->mres, &ucmd.rm); } if (err == LCB_SUCCESS) { rv = 0; } else { rv = -1; PYCBC_EXCTHROW_SCHED(err); } GT_DONE: Py_XDECREF(curkey); return rv; }
static int handle_single_kv(pycbc_Bucket *self, struct pycbc_common_vars *cv, int optype, PyObject *curkey, PyObject *curvalue, PyObject *options, pycbc_Item *itm, void *arg) { int rv; const struct storecmd_vars *scv = (struct storecmd_vars *)arg; struct single_key_context skc = { NULL }; const void *key, *value; size_t nkey, nvalue; lcb_error_t err; lcb_CMDSTORE cmd = { 0 }; skc.ttl = scv->ttl; skc.flagsobj = scv->flagsobj; skc.value = curvalue; skc.cas = scv->single_cas; rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv < 0) { return -1; } if (!nkey) { PYCBC_EXCTHROW_EMPTYKEY(); rv = -1; goto GT_DONE; } if (itm) { rv = handle_item_kv(itm, options, scv, &skc); if (rv < 0) { return -1; } } rv = pycbc_tc_encode_value(self, &skc.value, skc.flagsobj, (void**)&value, &nvalue, &cmd.flags); if (rv < 0) { skc.value = NULL; rv = -1; goto GT_DONE; } if (scv->operation == LCB_APPEND || scv->operation == LCB_PREPEND) { /* The server ignores these flags and libcouchbase will throw an error * if the flags are present. We check elsewhere here to ensure that * only UTF8/BYTES are accepted for append/prepend anyway */ cmd.flags = 0; } LCB_CMD_SET_KEY(&cmd, key, nkey); LCB_CMD_SET_VALUE(&cmd, value, nvalue); cmd.cas = skc.cas; cmd.operation = scv->operation; cmd.exptime = skc.ttl; err = lcb_store3(self->instance, cv->mres, &cmd); if (err == LCB_SUCCESS) { rv = 0; } else { rv = -1; PYCBC_EXCTHROW_SCHED(err); } GT_DONE: Py_XDECREF(curkey); Py_XDECREF(skc.value); return rv; }
PyObject * pycbc_Bucket_endure_multi(pycbc_Bucket *self, PyObject *args, PyObject *kwargs) { int rv; Py_ssize_t ncmds; pycbc_seqtype_t seqtype; char persist_to = 0, replicate_to = 0; lcb_durability_opts_t dopts = { 0 }; PyObject *keys; PyObject *is_delete_O = Py_False; lcb_error_t err; float timeout = 0.0; float interval = 0.0; struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT; static char *kwlist[] = { "keys", "persist_to", "replicate_to", "check_removed", "timeout", "interval", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "OBB|Off", kwlist, &keys, &persist_to, &replicate_to, &is_delete_O, &timeout, &interval); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } rv = pycbc_oputil_check_sequence(keys, 1, &ncmds, &seqtype); if (rv < 0) { return NULL; } rv = pycbc_common_vars_init(&cv, self, PYCBC_ARGOPT_MULTI, ncmds, 0); if (rv < 0) { return NULL; } dopts.v.v0.cap_max = persist_to < 0 || replicate_to < 0; dopts.v.v0.check_delete = is_delete_O && PyObject_IsTrue(is_delete_O); dopts.v.v0.timeout = (lcb_uint32_t)(timeout * 1000000.0); dopts.v.v0.interval = (lcb_uint32_t)(interval * 1000000.0); dopts.v.v0.persist_to = persist_to; dopts.v.v0.replicate_to = replicate_to; cv.mctx = lcb_endure3_ctxnew(self->instance, &dopts, &err); if (cv.mctx == NULL) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } rv = pycbc_oputil_iter_multi(self, seqtype, keys, &cv, PYCBC_CMD_ENDURE, handle_single_keyop, NULL); if (rv < 0) { 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; }
PyObject * pycbc_Bucket__stats(pycbc_Bucket *self, PyObject *args, PyObject *kwargs) { int rv; int ii; Py_ssize_t ncmds; lcb_error_t err = LCB_ERROR; PyObject *keys = NULL, *is_keystats = NULL; struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT; static char *kwlist[] = { "keys", "keystats", NULL }; lcb_CMDSTATS cmd = { 0 }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist, &keys, &is_keystats); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (keys == NULL || PyObject_IsTrue(keys) == 0) { keys = NULL; ncmds = 1; } else { if (!PySequence_Check(keys)) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "keys argument must be sequence"); return NULL; } ncmds = PySequence_Size(keys); } rv = pycbc_common_vars_init(&cv, self, PYCBC_ARGOPT_MULTI, ncmds, 0); if (rv < 0) { return NULL; } if (keys) { for (ii =0; ii < ncmds; ii++) { char *key; Py_ssize_t nkey; PyObject *newkey = NULL; PyObject *curkey = PySequence_GetItem(keys, ii); rv = pycbc_BufFromString(curkey, &key, &nkey, &newkey); if (rv < 0) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "bad key type in stats", curkey); goto GT_DONE; } LCB_CMD_SET_KEY(&cmd, key, nkey); if (is_keystats && PyObject_IsTrue(is_keystats)) { cmd.cmdflags |= LCB_CMDSTATS_F_KV; } err = lcb_stats3(self->instance, cv.mres, &cmd); Py_XDECREF(newkey); } } else { err = lcb_stats3(self->instance, cv.mres, &cmd); } 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; }
PyObject * pycbc_Connection__stats(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int ii; Py_ssize_t ncmds; lcb_error_t err; PyObject *keys = NULL; PyObject *ret = NULL; pycbc_MultiResult *mres = NULL; struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT; static char *kwlist[] = { "keys", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &keys); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (keys == NULL || PyObject_IsTrue(keys) == 0) { keys = NULL; ncmds = 1; } else { if (!PySequence_Check(keys)) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "keys argument must be sequence"); return NULL; } ncmds = PySequence_Size(keys); } rv = pycbc_common_vars_init(&cv, ncmds, sizeof(lcb_server_stats_cmd_t), 0); if (rv < 0) { return NULL; } if (keys) { for (ii =0; ii < ncmds; ii++) { char *key; Py_ssize_t nkey; PyObject *newkey = NULL; PyObject *curkey = PySequence_GetItem(keys, ii); lcb_server_stats_cmd_t *cmd = cv.cmds.stats + ii; rv = pycbc_BufFromString(curkey, &key, &nkey, &newkey); if (rv < 0) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "bad key type in stats", curkey); goto GT_DONE; } cmd->v.v0.name = key; cmd->v.v0.nname = nkey; cv.cmdlist.stats[ii] = cmd; cv.enckeys[ii] = newkey; } } else { cv.cmdlist.stats[0] = cv.cmds.stats; } mres = (pycbc_MultiResult*)pycbc_multiresult_new(self); err = lcb_server_stats(self->instance, mres, ncmds, cv.cmdlist.stats); 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; } ret = (PyObject*)mres; GT_DONE: pycbc_common_vars_free(&cv); /* Force multi, it's always a MultiResult */ pycbc_make_retval(PYCBC_ARGOPT_MULTI, &ret, &mres); Py_XDECREF(mres); return ret; }
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; }
PyObject * pycbc_Connection__http_request(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int method; int reqtype; int quiet = 0; unsigned short value_format = 0; lcb_error_t err; const char *body = NULL; PyObject *ret = NULL; PyObject *quiet_O = NULL; PyObject *fetch_headers_O = Py_False; pycbc_strlen_t nbody = 0; const char *path = NULL; const char *content_type = NULL; pycbc_HttpResult *htres; lcb_http_request_t htreq = NULL; lcb_http_cmd_t htcmd = { 0 }; static char *kwlist[] = { "type", "method", "path", "content_type", "post_data", "response_format", "quiet", "fetch_headers", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "iis|zz#HOO", kwlist, &reqtype, &method, &path, &content_type, &body, &nbody, &value_format, &quiet_O, &fetch_headers_O); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (quiet_O != NULL) { if (quiet_O == Py_None) { quiet = 0; } else { quiet = PyObject_IsTrue(quiet_O); } } htres = pycbc_httpresult_new(self); htres->key = pycbc_SimpleStringZ(path); htres->format = value_format; if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) { htres->headers = PyDict_New(); } htcmd.v.v1.body = body; htcmd.v.v1.nbody = nbody; htcmd.v.v1.content_type = content_type; htcmd.v.v1.path = path; htcmd.v.v1.npath = strlen(path); htcmd.v.v1.method = method; err = lcb_make_http_request(self->instance, htres, reqtype, &htcmd, &htreq); 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 (quiet == 0 && pycbc_httpresult_ok(htres) == 0) { PYCBC_EXC_WRAP_EX(htres->rc ? PYCBC_EXC_LCBERR : PYCBC_EXC_HTTP, htres->rc, "HTTP Request failed. Examine 'objextra' for " "full result", htres->key, (PyObject*)htres); goto GT_DONE; } ret = (PyObject*)htres; htres = NULL; GT_DONE: Py_XDECREF(htres); return ret; }
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; }
PyObject * pycbc_Connection__http_request(pycbc_Connection *self, PyObject *args, PyObject *kwargs) { int rv; int method; int reqtype; unsigned short value_format = 0; lcb_error_t err; const char *body = NULL; PyObject *ret = NULL; PyObject *quiet_O = NULL; PyObject *chunked_O = NULL; PyObject *fetch_headers_O = Py_False; pycbc_strlen_t nbody = 0; const char *path = NULL; const char *content_type = NULL; pycbc_HttpResult *htres; lcb_http_request_t l_htreq; lcb_http_cmd_t htcmd = { 0 }; static char *kwlist[] = { "type", "method", "path", "content_type", "post_data", "response_format", "quiet", "fetch_headers", "chunked", NULL }; rv = PyArg_ParseTupleAndKeywords(args, kwargs, "iis|zz#HOOO", kwlist, &reqtype, &method, &path, &content_type, &body, &nbody, &value_format, &quiet_O, &fetch_headers_O, &chunked_O); if (!rv) { PYCBC_EXCTHROW_ARGS(); return NULL; } if (-1 == pycbc_oputil_conn_lock(self)) { return NULL; } htres = pycbc_httpresult_new(self); htres->key = pycbc_SimpleStringZ(path); htres->format = value_format; htres->htflags = 0; if (quiet_O != NULL && quiet_O != Py_None && PyObject_IsTrue(quiet_O)) { htres->htflags |= PYCBC_HTRES_F_QUIET; } if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) { htres->headers = PyDict_New(); } if (chunked_O && PyObject_IsTrue(chunked_O)) { htcmd.v.v0.chunked = 1; htres->rctx = lcbex_vrow_create(); htres->rctx->callback = http_vrow_callback; htres->rctx->user_cookie = htres; htres->htflags |= PYCBC_HTRES_F_CHUNKED; } htcmd.v.v1.body = body; htcmd.v.v1.nbody = nbody; htcmd.v.v1.content_type = content_type; htcmd.v.v1.path = path; htcmd.v.v1.npath = strlen(path); htcmd.v.v1.method = method; err = lcb_make_http_request(self->instance, htres, reqtype, &htcmd, &l_htreq); if (err != LCB_SUCCESS) { PYCBC_EXCTHROW_SCHED(err); goto GT_DONE; } htres->htreq = l_htreq; if (htcmd.v.v0.chunked) { ret = (PyObject*)htres; htres = NULL; goto GT_DONE; } self->nremaining++; err = pycbc_oputil_wait_common(self); if (err != LCB_SUCCESS) { self->nremaining--; PYCBC_EXCTHROW_WAIT(err); goto GT_DONE; } if (maybe_raise(htres)) { goto GT_DONE; } ret = (PyObject*)htres; htres = NULL; GT_DONE: Py_XDECREF(htres); pycbc_oputil_conn_unlock(self); return ret; }