/** * 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_arith(pycbc_Bucket *self, struct pycbc_common_vars *cv, int optype, PyObject *curkey, PyObject *curvalue, PyObject *options, pycbc_Item *item, int ii, void *arg) { void *key; size_t nkey; int rv; lcb_arithmetic_cmd_t *acmd; struct arithmetic_common_vars my_params; static char *kwlist[] = { "delta", "initial", "ttl", NULL }; my_params = *(struct arithmetic_common_vars *)arg; (void)item; acmd = cv->cmds.arith + ii; rv = pycbc_tc_encode_key(self, &curkey, &key, &nkey); if (rv < 0) { return -1; } cv->enckeys[ii] = curkey; if (!nkey) { PYCBC_EXCTHROW_EMPTYKEY(); return -1; } if (options) { curvalue = options; } if (curvalue) { if (PyDict_Check(curvalue)) { PyObject *initial_O = NULL; rv = PyArg_ParseTupleAndKeywords(pycbc_DummyTuple, curvalue, "L|Ok", kwlist, &my_params.delta, &initial_O, &my_params.ttl); if (!rv) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "Couldn't parse parameter for key", curkey); return -1; } if (initial_O) { if (PyNumber_Check(initial_O)) { my_params.create = 1; my_params.initial = pycbc_IntAsULL(initial_O); } else { my_params.create = 0; } } } else if (PyNumber_Check(curvalue)) { my_params.delta = pycbc_IntAsLL(curvalue); } else { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "value for key must be an integer amount " "or a dict of parameters", curkey); return -1; } } acmd->v.v0.key = key; acmd->v.v0.nkey = nkey; acmd->v.v0.delta = my_params.delta; acmd->v.v0.create = my_params.create; acmd->v.v0.exptime = my_params.ttl; acmd->v.v0.initial = my_params.initial; cv->cmdlist.arith[ii] = acmd; return 0; }
/** * This is called during each iteration of delete/unlock */ static int handle_single_keyop(pycbc_Connection *self, PyObject *curkey, PyObject *curval, int ii, int optype, struct pycbc_common_vars *cv) { int rv; char *key; size_t nkey; lcb_uint64_t cas = 0; rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv == -1) { return -1; } cv->enckeys[ii] = curkey; 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; } } if (optype == PYCBC_CMD_UNLOCK) { lcb_unlock_cmd_t *ucmd = cv->cmds.unlock + ii; if (!cas) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "CAS must be specified for unlock"); } ucmd->v.v0.key = key; ucmd->v.v0.nkey = nkey; ucmd->v.v0.cas = cas; cv->cmdlist.unlock[ii] = ucmd; return 0; } else { lcb_remove_cmd_t *rcmd = cv->cmds.remove + ii; rcmd->v.v0.key = key; rcmd->v.v0.nkey = nkey; rcmd->v.v0.cas = cas; cv->cmdlist.remove[ii] = rcmd; return 0; } }
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; }