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;
}
Exemplo n.º 2
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;
}