예제 #1
0
/**
 * 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;
}
예제 #2
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;
    }
}