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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
    }
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
}