static int handle_single_observe(pycbc_Connection *self, PyObject *curkey, int ii, int master_only, struct pycbc_common_vars *cv) { int rv; char *key; size_t nkey; lcb_observe_cmd_t *ocmd = cv->cmds.obs + ii; rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv < 0) { return -1; } cv->enckeys[ii] = curkey; if (!nkey) { PYCBC_EXCTHROW_EMPTYKEY(); return -1; } if (master_only) { /** New 'MASTER_ONLY' was added in 2.3.0 */ #if LCB_VERSION < 0x020300 PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "master_only requires libcouchbase >= 2.3.0"); return -1; #else ocmd->version = 1; ocmd->v.v1.options = LCB_OBSERVE_MASTER_ONLY; #endif } ocmd->v.v0.key = key; ocmd->v.v0.nkey = nkey; cv->cmdlist.obs[ii] = ocmd; return 0; }
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; }
/** * 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; }
/** * 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; } }
static int handle_single_key(pycbc_Connection *self, PyObject *curkey, PyObject *curval, unsigned long ttl, int ii, int optype, struct pycbc_common_vars *cv) { int rv; char *key; size_t nkey; unsigned int lock = 0; rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv == -1) { return -1; } cv->enckeys[ii] = curkey; if (curval) { static char *kwlist[] = { "ttl", NULL }; PyObject *ttl_O = NULL; if (ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Both global and single TTL specified"); return -1; } if (PyDict_Check(curval)) { rv = PyArg_ParseTupleAndKeywords(pycbc_DummyTuple, curval, "|O", kwlist, &ttl_O); if (!rv) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "Couldn't get sub-parmeters for key", curkey); return -1; } } else { ttl_O = curval; } rv = pycbc_get_ttl(ttl_O, &ttl, 1); if (rv < 0) { return -1; } } switch (optype) { case PYCBC_CMD_GAT: if (!ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "GAT must have positive TTL"); return -1; } goto GT_GET; case PYCBC_CMD_LOCK: if (!ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Lock must have an expiry"); } lock = 1; goto GT_GET; case PYCBC_CMD_GET: GT_GET: { lcb_get_cmd_t *gcmd = cv->cmds.get + ii; gcmd->v.v0.lock = lock; gcmd->v.v0.key = key; gcmd->v.v0.nkey = nkey; gcmd->v.v0.exptime = ttl; cv->cmdlist.get[ii] = gcmd; } break; case PYCBC_CMD_TOUCH: { lcb_touch_cmd_t *tcmd = cv->cmds.touch + ii; tcmd->v.v0.key = key; tcmd->v.v0.nkey = nkey; tcmd->v.v0.exptime = ttl; cv->cmdlist.touch[ii] = tcmd; break; } } return 0; }
static int handle_single_key(pycbc_Connection *self, struct pycbc_common_vars *cv, int optype, PyObject *curkey, PyObject *curval, PyObject *options, pycbc_Item *itm, int ii, void *arg) { int rv; char *key; size_t nkey; unsigned int lock = 0; struct getcmd_vars_st *gv = (struct getcmd_vars_st *)arg; unsigned long ttl = gv->u.ttl; (void)itm; rv = pycbc_tc_encode_key(self, &curkey, (void**)&key, &nkey); if (rv == -1) { return -1; } cv->enckeys[ii] = curkey; if (!nkey) { PYCBC_EXCTHROW_EMPTYKEY(); return -1; } if (curval && gv->allow_dval && options == NULL) { options = curval; } if (options) { static char *kwlist[] = { "ttl", NULL }; PyObject *ttl_O = NULL; if (gv->u.ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Both global and single TTL specified"); return -1; } if (PyDict_Check(curval)) { rv = PyArg_ParseTupleAndKeywords(pycbc_DummyTuple, curval, "|O", kwlist, &ttl_O); if (!rv) { PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "Couldn't get sub-parmeters for key", curkey); return -1; } } else { ttl_O = curval; } rv = pycbc_get_ttl(ttl_O, &ttl, 1); if (rv < 0) { return -1; } } switch (optype) { case PYCBC_CMD_GAT: if (!ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "GAT must have positive TTL"); return -1; } goto GT_GET; case PYCBC_CMD_LOCK: if (!ttl) { PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Lock must have an expiry"); return -1; } lock = 1; goto GT_GET; case PYCBC_CMD_GET: GT_GET: { lcb_get_cmd_t *gcmd = cv->cmds.get + ii; gcmd->v.v0.lock = lock; gcmd->v.v0.key = key; gcmd->v.v0.nkey = nkey; gcmd->v.v0.exptime = ttl; cv->cmdlist.get[ii] = gcmd; } break; case PYCBC_CMD_TOUCH: { lcb_touch_cmd_t *tcmd = cv->cmds.touch + ii; tcmd->v.v0.key = key; tcmd->v.v0.nkey = nkey; tcmd->v.v0.exptime = ttl; cv->cmdlist.touch[ii] = tcmd; break; } case PYCBC_CMD_GETREPLICA: case PYCBC_CMD_GETREPLICA_INDEX: case PYCBC_CMD_GETREPLICA_ALL: { lcb_get_replica_cmd_t *rcmd = cv->cmds.replica + ii; rcmd->version = 1; rcmd->v.v1.key = key; rcmd->v.v1.nkey = nkey; rcmd->v.v1.nkey = nkey; rcmd->v.v1.strategy = gv->u.replica.strategy; rcmd->v.v1.index = gv->u.replica.index; cv->cmdlist.replica[ii] = rcmd; break; } } return 0; }
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; }