Exemplo n.º 1
0
PyObject *
pycbc_Connection__vbmap(pycbc_Connection *conn, PyObject *args)
{
    pycbc_strlen_t slen = 0;
    const char *s = NULL;
    PyObject *rtuple;
    struct vbinfo_st info;
    lcb_error_t err;

    if (!PyArg_ParseTuple(args, "s#", &s, &slen)) {
        PYCBC_EXCTHROW_ARGS();
    }

    memset(&info, 0, sizeof(info));
    info.v.v0.key = s;
    info.v.v0.nkey = slen;
    err = lcb_cntl(conn->instance, CNTL_GET, CNTL_VBMAP, &info);
    if (err != LCB_SUCCESS) {
        PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "lcb_cntl failed");
        return NULL;
    }

    rtuple = PyTuple_New(2);
    PyTuple_SET_ITEM(rtuple, 0, pycbc_IntFromL(info.v.v0.vbucket));
    PyTuple_SET_ITEM(rtuple, 1, pycbc_IntFromL(info.v.v0.server_index));
    return rtuple;

}
Exemplo n.º 2
0
static PyObject *
handle_float_tmo(lcb_t instance,
                 int cmd, int mode, PyObject *val, lcb_error_t *err)
{
    lcb_uint32_t cval;

    if (val != NULL) {
        if (PyFloat_Check(val)) {
            double dv = PyFloat_AsDouble(val);
            if (dv < 0) {
                PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0,
                               "Timeout cannot be < 0");
                return NULL;
            }
            cval = dv * 1000000;

        } else {
        cval = pycbc_IntAsL(val);
            if (cval == (lcb_uint32_t)-1 && PyErr_Occurred()) {
                PYCBC_EXCTHROW_ARGS();
                return NULL;
            }
        }
    }
    if ( (*err = lcb_cntl(instance, mode, cmd, &cval)) != LCB_SUCCESS) {
        return NULL;
    }

    return pycbc_IntFromUL(cval);
}
Exemplo n.º 3
0
PyObject *
pycbc_Bucket__fts_query(pycbc_Bucket *self, PyObject *args, PyObject *kwargs)
{
    int rv;
    PyObject *ret = NULL;
    pycbc_MultiResult *mres;
    pycbc_ViewResult *vres;
    lcb_error_t rc;
    lcb_CMDFTS cmd = { 0 };
    const char *params;
    pycbc_strlen_t nparams;

    static char *kwlist[] = { "params", NULL };
    rv = PyArg_ParseTupleAndKeywords(args, kwargs,
        "s#", kwlist, &params, &nparams);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }
    if (-1 == pycbc_oputil_conn_lock(self)) {
        return NULL;
    }
    if (self->pipeline_queue) {
        PYCBC_EXC_WRAP(PYCBC_EXC_PIPELINE, 0,
                       "FTS queries cannot be executed in pipeline context");
    }

    mres = (pycbc_MultiResult *)pycbc_multiresult_new(self);
    vres = (pycbc_ViewResult *)PYCBC_TYPE_CTOR(&pycbc_ViewResultType);
    pycbc_httpresult_init(&vres->base, mres);
    vres->rows = PyList_New(0);
    vres->base.format = PYCBC_FMT_JSON;
    vres->base.htype = PYCBC_HTTP_HN1QL;

    cmd.callback = fts_row_callback;
    cmd.query = params;
    cmd.nquery = nparams;
    cmd.handle = &vres->base.u.fts;
    rc = lcb_fts_query(self->instance, mres, &cmd);

    if (rc != LCB_SUCCESS) {
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, rc, "Couldn't schedule fts query");
        goto GT_DONE;
    }

    ret = (PyObject *)mres;
    mres = NULL;

    GT_DONE:
    Py_XDECREF(mres);
    pycbc_oputil_conn_unlock(self);
    return ret;
}
Exemplo n.º 4
0
static PyObject *
handle_intval(lcb_t instance,
              int cmd, int mode, PyObject *val, lcb_error_t *err)
{
    int cval;

    if (val != NULL) {
        cval = pycbc_IntAsL(val);
        if (cval == -1 && PyErr_Occurred()) {
            PYCBC_EXCTHROW_ARGS();
        }
    }

    if ((*err = lcb_cntl(instance, mode, cmd, &cval)) != LCB_SUCCESS) {
        return NULL;
    }

    return pycbc_IntFromL(cval);

}
Exemplo n.º 5
0
static PyObject *
ViewResult_fetch(pycbc_ViewResult *self, PyObject *args)
{
    PyObject *ret = NULL;
    pycbc_MultiResult *mres = NULL;
    pycbc_Bucket *bucket;
    int rv;

    rv = PyArg_ParseTuple(args, "O", &mres);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    bucket = mres->parent;

    if (bucket->flags & PYCBC_CONN_F_ASYNC) {
        PYCBC_EXC_WRAP(PYCBC_EXC_INTERNAL, 0, "Cannot use fetch with async");
        return NULL;
    }

    if (-1 == pycbc_oputil_conn_lock(bucket)) {
        return NULL;
    }

    if (!self->base.done) {
        pycbc_oputil_wait_common(bucket);
    }

    if (pycbc_multiresult_maybe_raise(mres)) {
        goto GT_DONE;
    }

    ret = self->rows ? self->rows : PyList_New(0);
    self->rows = PyList_New(0);

    GT_DONE:
    pycbc_oputil_conn_unlock(bucket);
    return ret;
}
Exemplo n.º 6
0
static PyObject*
get_common(pycbc_Connection *self,
           PyObject *args,
           PyObject *kwargs,
           int optype,
           int argopts)
{
    int rv;
    Py_ssize_t ncmds = 0;
    size_t cmdsize;
    pycbc_seqtype_t seqtype;
    PyObject *kobj = NULL;
    PyObject *is_quiet = NULL;
    lcb_error_t err;

    PyObject *ttl_O = NULL;
    PyObject *replica_O = NULL;
    PyObject *nofmt_O = NULL;

    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;
    struct getcmd_vars_st gv = { 0 };
    static char *kwlist[] = {
            "keys", "ttl", "quiet", "replica", "no_format", NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args,
                                     kwargs,
                                     "O|OOOO",
                                     kwlist,
                                     &kobj,
                                     &ttl_O,
                                     &is_quiet,
                                     &replica_O,
                                     &nofmt_O);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS()
        return NULL;
    }
Exemplo n.º 7
0
static PyObject*
get_common(pycbc_Connection *self,
           PyObject *args,
           PyObject *kwargs,
           int optype,
           int argopts)
{
    int rv;
    int ii;
    Py_ssize_t ncmds = 0;
    size_t cmdsize;
    pycbc_seqtype_t seqtype;
    PyObject *ret = NULL;
    PyObject *kobj = NULL;
    PyObject *is_quiet = NULL;
    pycbc_MultiResult *mres = NULL;
    lcb_error_t err;
    PyObject *ttl_O = NULL;
    unsigned long ttl = 0;

    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;

    static char *kwlist[] = { "keys", "ttl", "quiet", NULL };

    rv = PyArg_ParseTupleAndKeywords(args,
                                     kwargs,
                                     "O|OO",
                                     kwlist,
                                     &kobj,
                                     &ttl_O,
                                     &is_quiet);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS()
        return NULL;
    }
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.º 9
0
static int
Connection__init__(pycbc_Connection *self,
                       PyObject *args, PyObject *kwargs)
{
    int rv;
    int conntype = LCB_TYPE_BUCKET;
    lcb_error_t err;
    char *conncache = NULL;
    PyObject *unlock_gil_O = NULL;
    PyObject *iops_O = NULL;
    PyObject *timeout = NULL;
    PyObject *dfl_fmt = NULL;
    PyObject *tc = NULL;

    struct lcb_create_st create_opts = { 0 };
    struct lcb_cached_config_st cached_config = { { 0 } };


    /**
     * This xmacro enumerates the constructor keywords, targets, and types.
     * This was converted into an xmacro to ease the process of adding or
     * removing various parameters.
     */
#define XCTOR_ARGS(X) \
    X("_errors", &self->errors, "O") \
    X("_flags", &self->flags, "I") \
    X("bucket", &create_opts.v.v1.bucket, "z") \
    X("username", &create_opts.v.v1.user, "z") \
    X("password", &create_opts.v.v1.passwd, "z") \
    X("host", &create_opts.v.v1.host, "z") \
    X("conncache", &conncache, "z") \
    X("quiet", &self->quiet, "I") \
    X("unlock_gil", &unlock_gil_O, "O") \
    X("transcoder", &tc, "O") \
    X("timeout", &timeout, "O") \
    X("default_format", &dfl_fmt, "O") \
    X("lockmode", &self->lockmode, "i") \
    X("_conntype", &conntype, "i") \
    X("_iops", &iops_O, "O")

    static char *kwlist[] = {
        #define X(s, target, type) s,
            XCTOR_ARGS(X)
        #undef X

            NULL
    };

    #define X(s, target, type) type
    static char *argspec = "|" XCTOR_ARGS(X);
    #undef X

    if (self->init_called) {
        PyErr_SetString(PyExc_RuntimeError, "__init__ was already called");
        return -1;
    }

    self->init_called = 1;
    self->flags = 0;
    self->unlock_gil = 1;
    self->lockmode = PYCBC_LOCKMODE_EXC;

    #define X(s, target, type) target,
    rv = PyArg_ParseTupleAndKeywords(args,
                                     kwargs,
                                     argspec,
                                     kwlist,
                                     XCTOR_ARGS(X) NULL);
    #undef X

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return -1;
    }

    if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) {
        self->unlock_gil = 0;
    }

    if (create_opts.v.v1.bucket) {
        self->bucket = pycbc_SimpleStringZ(create_opts.v.v1.bucket);
    }

    create_opts.version = 1;
    create_opts.v.v1.type = conntype;

    if (iops_O && iops_O != Py_None) {
        self->iops = pycbc_iops_new(self, iops_O);
        create_opts.v.v1.io = self->iops;
        self->unlock_gil = 0;
    }

    Py_INCREF(self->errors);


    if (dfl_fmt == Py_None || dfl_fmt == NULL) {
        /** Set to 0 if None or NULL */
        dfl_fmt = pycbc_IntFromL(0);

    } else {
        Py_INCREF(dfl_fmt); /* later decref */
    }

    rv = Connection_set_format(self, dfl_fmt, NULL);
    Py_XDECREF(dfl_fmt);
    if (rv == -1) {
        return rv;
    }

    /** Set the transcoder */
    if (tc && Connection_set_transcoder(self, tc, NULL) == -1) {
        return -1;
    }

#ifdef WITH_THREAD
    if (!self->unlock_gil) {
        self->lockmode = PYCBC_LOCKMODE_NONE;
    }

    if (self->lockmode != PYCBC_LOCKMODE_NONE) {
        self->lock = PyThread_allocate_lock();
    }
#endif

    if (conncache) {
        if (conntype != LCB_TYPE_BUCKET) {
            PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0,
                           "Cannot use connection cache with "
                           "management connection");
            return -1;
        }
        cached_config.cachefile = conncache;
        memcpy(&cached_config.createopt, &create_opts, sizeof(create_opts));
        err = lcb_create_compat(LCB_CACHED_CONFIG,
                                &cached_config,
                                &self->instance,
                                NULL);
    } else {
        err = lcb_create(&self->instance, &create_opts);
    }

    if (err != LCB_SUCCESS) {
        self->instance = NULL;
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err,
                       "Couldn't create instance. Either bad "
                       "credentials/hosts/bucket names were "
                       "passed, or there was an internal error in creating the "
                       "object");
        return -1;
    }

    pycbc_callbacks_init(self->instance);
    lcb_set_cookie(self->instance, self);

    if (timeout && timeout != Py_None) {
        if (Connection_set_timeout(self, timeout, NULL) == -1) {
            return -1;
        }
    }

    PYCBC_CONN_THR_BEGIN(self);
    err = lcb_connect(self->instance);
    PYCBC_CONN_THR_END(self);

    if (err != LCB_SUCCESS) {
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err,
                       "Couldn't schedule connection. This might be a result of "
                       "an invalid hostname.");
        return -1;
    }


    err = pycbc_oputil_wait_common(self);

    if (err != LCB_SUCCESS) {
        PYCBC_EXCTHROW_WAIT(err);
        return -1;
    }

    return 0;
}
Exemplo n.º 10
0
PyObject *
pycbc_Bucket__n1ql_query(pycbc_Bucket *self, PyObject *args, PyObject *kwargs)
{
    int rv;
    PyObject *ret = NULL;
    pycbc_MultiResult *mres;
    pycbc_ViewResult *vres;
    lcb_error_t rc;
    lcb_CMDN1QL cmd = { 0 };
    const char *params;
    pycbc_strlen_t nparams;
    int prepared = 0, cross_bucket = 0;

    static char *kwlist[] = { "params", "prepare", "cross_bucket", NULL };
    rv = PyArg_ParseTupleAndKeywords(
        args, kwargs, "s#|ii", kwlist, &params, &nparams, &prepared, &cross_bucket);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }
    if (-1 == pycbc_oputil_conn_lock(self)) {
        return NULL;
    }
    if (self->pipeline_queue) {
        PYCBC_EXC_WRAP(PYCBC_EXC_PIPELINE, 0,
                       "N1QL queries cannot be executed in "
                       "pipeline context");
    }

    mres = (pycbc_MultiResult *)pycbc_multiresult_new(self);
    vres = (pycbc_ViewResult *)PYCBC_TYPE_CTOR(&pycbc_ViewResultType);
    pycbc_httpresult_init(&vres->base, mres);
    vres->rows = PyList_New(0);
    vres->base.format = PYCBC_FMT_JSON;
    vres->base.htype = PYCBC_HTTP_HN1QL;

    cmd.content_type = "application/json";
    cmd.callback = n1ql_row_callback;
    cmd.query = params;
    cmd.nquery = nparams;
    cmd.handle = &vres->base.u.nq;
    if (prepared) {
        cmd.cmdflags |= LCB_CMDN1QL_F_PREPCACHE;
    }
    if (cross_bucket) {
        cmd.cmdflags |= LCB_CMD_F_MULTIAUTH;
    }
    rc = lcb_n1ql_query(self->instance, mres, &cmd);

    if (rc != LCB_SUCCESS) {
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, rc, "Couldn't schedule n1ql query");
        goto GT_DONE;
    }

    ret = (PyObject *)mres;
    mres = NULL;

    GT_DONE:
    Py_XDECREF(mres);
    pycbc_oputil_conn_unlock(self);
    return ret;
}
Exemplo n.º 11
0
PyObject *
pycbc_Bucket__stats(pycbc_Bucket *self, PyObject *args, PyObject *kwargs)
{
    int rv;
    int ii;
    Py_ssize_t ncmds;
    lcb_error_t err = LCB_ERROR;
    PyObject *keys = NULL, *is_keystats = NULL;
    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;
    static char *kwlist[] = {  "keys", "keystats", NULL };
    lcb_CMDSTATS cmd = { 0 };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", kwlist,
        &keys, &is_keystats);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    if (keys == NULL || PyObject_IsTrue(keys) == 0) {
        keys = NULL;
        ncmds = 1;

    } else {
        if (!PySequence_Check(keys)) {
            PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "keys argument must be sequence");
            return NULL;
        }
        ncmds = PySequence_Size(keys);
    }

    rv = pycbc_common_vars_init(&cv, self, PYCBC_ARGOPT_MULTI, ncmds, 0);
    if (rv < 0) {
        return NULL;
    }

    if (keys) {
        for (ii =0; ii < ncmds; ii++) {
            char *key;
            Py_ssize_t nkey;
            PyObject *newkey = NULL;

            PyObject *curkey = PySequence_GetItem(keys, ii);
            rv = pycbc_BufFromString(curkey, &key, &nkey, &newkey);
            if (rv < 0) {
                PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS, 0, "bad key type in stats", curkey);
                goto GT_DONE;
            }

            LCB_CMD_SET_KEY(&cmd, key, nkey);
            if (is_keystats && PyObject_IsTrue(is_keystats)) {
                cmd.cmdflags |= LCB_CMDSTATS_F_KV;
            }
            err = lcb_stats3(self->instance, cv.mres, &cmd);
            Py_XDECREF(newkey);
        }

    } else {
        err = lcb_stats3(self->instance, cv.mres, &cmd);
    }

    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;
}
Exemplo n.º 12
0
PyObject *
pycbc_Bucket_endure_multi(pycbc_Bucket *self, PyObject *args, PyObject *kwargs)
{
    int rv;
    Py_ssize_t ncmds;
    pycbc_seqtype_t seqtype;
    char persist_to = 0, replicate_to = 0;
    lcb_durability_opts_t dopts = { 0 };
    PyObject *keys;
    PyObject *is_delete_O = Py_False;
    lcb_error_t err;
    float timeout = 0.0;
    float interval = 0.0;

    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;

    static char *kwlist[] = {
            "keys",
            "persist_to",
            "replicate_to",
            "check_removed",
            "timeout",
            "interval",
            NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs, "OBB|Off", kwlist,
                                     &keys,
                                     &persist_to, &replicate_to,
                                     &is_delete_O, &timeout, &interval);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    rv = pycbc_oputil_check_sequence(keys, 1, &ncmds, &seqtype);
    if (rv < 0) {
        return NULL;
    }
    rv = pycbc_common_vars_init(&cv, self, PYCBC_ARGOPT_MULTI, ncmds, 0);
    if (rv < 0) {
        return NULL;
    }

    dopts.v.v0.cap_max = persist_to < 0 || replicate_to < 0;
    dopts.v.v0.check_delete = is_delete_O && PyObject_IsTrue(is_delete_O);
    dopts.v.v0.timeout = (lcb_uint32_t)(timeout * 1000000.0);
    dopts.v.v0.interval = (lcb_uint32_t)(interval * 1000000.0);
    dopts.v.v0.persist_to = persist_to;
    dopts.v.v0.replicate_to = replicate_to;
    cv.mctx = lcb_endure3_ctxnew(self->instance, &dopts, &err);
    if (cv.mctx == NULL) {
        PYCBC_EXCTHROW_SCHED(err);
        goto GT_DONE;
    }

    rv = pycbc_oputil_iter_multi(self, seqtype, keys, &cv, PYCBC_CMD_ENDURE,
                                 handle_single_keyop, NULL);
    if (rv < 0) {
        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;

}
Exemplo n.º 13
0
static PyObject *
keyop_common(pycbc_Bucket *self, PyObject *args, PyObject *kwargs, int optype,
    int argopts)
{
    int rv;
    Py_ssize_t ncmds = 0;
    pycbc_seqtype_t seqtype;
    PyObject *casobj = NULL;
    PyObject *is_quiet = NULL;
    PyObject *kobj = NULL;
    char persist_to = 0, replicate_to = 0;
    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;

    static char *kwlist[] = {
            "keys", "cas", "quiet", "persist_to", "replicate_to", NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args,
                                     kwargs,
                                     "O|OOBB",
                                     kwlist,
                                     &kobj,
                                     &casobj,
                                     &is_quiet,
                                     &persist_to, &replicate_to);

    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, self, argopts, ncmds, 0);
    if (rv < 0) {
        return NULL;
    }

    if (argopts & PYCBC_ARGOPT_MULTI) {
        rv = pycbc_oputil_iter_multi(self, seqtype, kobj, &cv, optype,
                                     handle_single_keyop, NULL);
    } else {
        rv = handle_single_keyop(self, &cv, optype, kobj, casobj, NULL, NULL, NULL);
    }

    if (rv < 0) {
        goto GT_DONE;
    }

    if (optype == PYCBC_CMD_DELETE) {
        rv = pycbc_handle_durability_args(self, &cv.mres->dur,
                                          persist_to, replicate_to);
        if (rv == 1) {
            cv.mres->mropts |= PYCBC_MRES_F_DURABILITY;

        } else if (rv == -1) {
            goto GT_DONE;
        }
        if (pycbc_maybe_set_quiet(cv.mres, is_quiet) == -1) {
            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;
}
Exemplo n.º 14
0
PyObject *
pycbc_Connection__stats(pycbc_Connection *self,
                        PyObject *args,
                        PyObject *kwargs)
{
    int rv;
    int ii;
    Py_ssize_t ncmds;
    lcb_error_t err;
    PyObject *keys = NULL;
    PyObject *ret = NULL;
    pycbc_MultiResult *mres = NULL;
    struct pycbc_common_vars cv = PYCBC_COMMON_VARS_STATIC_INIT;
    static char *kwlist[] = {  "keys", NULL };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &keys);

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    if (keys == NULL || PyObject_IsTrue(keys) == 0) {
        keys = NULL;
        ncmds = 1;

    } else {
        if (!PySequence_Check(keys)) {
            PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "keys argument must be sequence");
            return NULL;
        }
        ncmds = PySequence_Size(keys);
    }

    rv = pycbc_common_vars_init(&cv, ncmds, sizeof(lcb_server_stats_cmd_t), 0);
    if (rv < 0) {
        return NULL;
    }

    if (keys) {
        for (ii =0; ii < ncmds; ii++) {
            char *key;
            Py_ssize_t nkey;
            PyObject *newkey = NULL;

            PyObject *curkey = PySequence_GetItem(keys, ii);
            lcb_server_stats_cmd_t *cmd = cv.cmds.stats + ii;
            rv = pycbc_BufFromString(curkey, &key, &nkey, &newkey);
            if (rv < 0) {
                PYCBC_EXC_WRAP_KEY(PYCBC_EXC_ARGUMENTS,
                                   0,
                                   "bad key type in stats",
                                   curkey);
                goto GT_DONE;
            }

            cmd->v.v0.name = key;
            cmd->v.v0.nname = nkey;
            cv.cmdlist.stats[ii] = cmd;
            cv.enckeys[ii] = newkey;
        }

    } else {
        cv.cmdlist.stats[0] = cv.cmds.stats;
    }


    mres = (pycbc_MultiResult*)pycbc_multiresult_new(self);

    err = lcb_server_stats(self->instance, mres, ncmds, cv.cmdlist.stats);
    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;
    }

    ret = (PyObject*)mres;

    GT_DONE:
    pycbc_common_vars_free(&cv);

    /* Force multi, it's always a MultiResult */
    pycbc_make_retval(PYCBC_ARGOPT_MULTI, &ret, &mres);
    Py_XDECREF(mres);
    return ret;
}
Exemplo n.º 15
0
PyObject *
pycbc_Connection__cntl(pycbc_Connection *self, PyObject *args)
{
    int cmd = 0, mode = 0;
    PyObject *val = NULL;
    PyObject *ret = NULL;
    lcb_error_t err = LCB_SUCCESS;

    if (!PyArg_ParseTuple(args, "i|O", &cmd, &val)) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    mode = (val == NULL) ? CNTL_GET : CNTL_SET;

    switch (cmd) {

    /** Timeout parameters */
    case CNTL_OP_TIMEOUT:
    case CNTL_VIEW_TIMEOUT:
    case CNTL_HTTP_TIMEOUT:
    case CNTL_DURABILITY_INTERVAL:
    case CNTL_DURABILITY_TIMEOUT:
    case CNTL_CONFIGURATION_TIMEOUT: {
        ret = handle_float_tmo(self->instance, cmd, mode, val, &err);
        if (ret) {
            return ret;
        }
        break;
    }

    /** Boolean values */
    case CNTL_SKIP_CONFIGURATION_ERRORS_ON_CONNECT:
    case CNTL_RANDOMIZE_BOOTSTRAP_HOSTS:
    case CNTL_CONFIG_CACHE_LOADED: {
        ret = handle_boolean(self->instance, cmd, mode, val, &err);
        break;
    }

    /** int values */
    case CNTL_MAX_REDIRECTS: {
        ret = handle_intval(self->instance, cmd, mode, val, &err);
        break;
    }

    default: {
        if (val == NULL) {
            PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0, "Unknown cntl");
            return NULL;

        } else {
            if (PyBool_Check(val)) {
                ret = handle_boolean(self->instance, cmd, mode, val, &err);
            } else if (PyFloat_Check(val)) {
                ret = handle_float_tmo(self->instance, cmd, mode, val, &err);
            } else if (PyNumber_Check(val)) {
                ret = handle_float_tmo(self->instance, cmd, mode, val, &err);
            } else {
                PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, 0,
                               "Couldn't determine type for cntl");
                return NULL;
            }
        }

        /** not reached */
        abort();
        break;
    }
    }

    if (ret) {
        return ret;
    }

    PYCBC_EXC_WRAP(PYCBC_EXC_ARGUMENTS, err, "lcb_cntl failed");
    return NULL;
}
Exemplo n.º 16
0
PyObject *
pycbc_Bucket__view_request(pycbc_Bucket *self, PyObject *args, PyObject *kwargs)
{
    int rv;
    PyObject *ret = NULL;
    pycbc_MultiResult *mres = NULL;
    pycbc_ViewResult *vres = NULL;
    lcb_CMDVIEWQUERY vcmd = { 0 };
    viewpath_st vp = { NULL };
    lcb_error_t rc;
    const char *view = NULL, *design = NULL;
    PyObject *options = NULL;
    int flags;

    static char *kwlist[] = { "design", "view", "options", "_flags", NULL };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs, "ss|Oi", kwlist,
                                     &design, &view, &options, &flags);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }
    if (-1 == pycbc_oputil_conn_lock(self)) {
        return NULL;
    }

    if (self->pipeline_queue) {
        PYCBC_EXC_WRAP(PYCBC_EXC_PIPELINE, 0,
                       "HTTP/View Requests cannot be executed in "
                       "pipeline context");
        goto GT_DONE;
    }

    mres = (pycbc_MultiResult *)pycbc_multiresult_new(self);
    vres = (pycbc_ViewResult *)PYCBC_TYPE_CTOR(&pycbc_ViewResultType);
    vres->base.htype = PYCBC_HTTP_HVIEW;

    pycbc_httpresult_init(&vres->base, mres);

    rv = get_viewpath_str(self, &vp, options);
    if (rv != 0) {
        goto GT_DONE;
    }

    vcmd.ddoc = design;
    vcmd.nddoc = strlen(design);
    vcmd.view = view;
    vcmd.nview = strlen(view);
    vcmd.optstr = vp.optstr;
    vcmd.noptstr = vp.noptstr;
    vcmd.postdata = vp.body;
    vcmd.npostdata = vp.nbody;
    vcmd.handle = &vres->base.u.vh;
    vcmd.callback = row_callback;
    vcmd.cmdflags = flags;

    vres->rows = PyList_New(0);
    vres->base.format = PYCBC_FMT_JSON;

    rc = lcb_view_query(self->instance, mres, &vcmd);

    if (rc != LCB_SUCCESS) {
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, rc, "Couldn't schedule view");
        goto GT_DONE;
    }

    ret = (PyObject*)mres;
    mres = NULL; /* Avoid GT_DONE decref */

    GT_DONE:
    Py_XDECREF(mres);
    Py_XDECREF(vp.bk);
    pycbc_oputil_conn_unlock(self);
    return ret;
}
Exemplo n.º 17
0
static int
Bucket__init__(pycbc_Bucket *self,
                       PyObject *args, PyObject *kwargs)
{
    int rv;
    int conntype = LCB_TYPE_BUCKET;

    lcb_error_t err;
    PyObject *unlock_gil_O = NULL;
    PyObject *iops_O = NULL;
    PyObject *dfl_fmt = NULL;
    PyObject *tc = NULL;

    struct lcb_create_st create_opts = { 0 };


    /**
     * This xmacro enumerates the constructor keywords, targets, and types.
     * This was converted into an xmacro to ease the process of adding or
     * removing various parameters.
     */
#define XCTOR_ARGS(X) \
    X("connection_string", &create_opts.v.v3.connstr, "z") \
    X("connstr", &create_opts.v.v3.connstr, "z") \
    X("username", &create_opts.v.v3.username, "z") \
    X("password", &create_opts.v.v3.passwd, "z") \
    X("quiet", &self->quiet, "I") \
    X("unlock_gil", &unlock_gil_O, "O") \
    X("transcoder", &tc, "O") \
    X("default_format", &dfl_fmt, "O") \
    X("lockmode", &self->lockmode, "i") \
    X("_flags", &self->flags, "I") \
    X("_conntype", &conntype, "i") \
    X("_iops", &iops_O, "O")

    static char *kwlist[] = {
        #define X(s, target, type) s,
            XCTOR_ARGS(X)
        #undef X
            NULL
    };

    #define X(s, target, type) type
    static char *argspec = "|" XCTOR_ARGS(X);
    #undef X

    if (self->init_called) {
        PyErr_SetString(PyExc_RuntimeError, "__init__ was already called");
        return -1;
    }

    self->init_called = 1;
    self->flags = 0;
    self->unlock_gil = 1;
    self->lockmode = PYCBC_LOCKMODE_EXC;

    #define X(s, target, type) target,
    rv = PyArg_ParseTupleAndKeywords(args, kwargs, argspec, kwlist,
        XCTOR_ARGS(X) NULL);
    #undef X

    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return -1;
    }

    if (unlock_gil_O && PyObject_IsTrue(unlock_gil_O) == 0) {
        self->unlock_gil = 0;
    }

    create_opts.version = 3;
    create_opts.v.v3.type = conntype;

    if (iops_O && iops_O != Py_None) {
        self->iopswrap = pycbc_iowrap_new(self, iops_O);
        create_opts.v.v3.io = pycbc_iowrap_getiops(self->iopswrap);
        self->unlock_gil = 0;
    }

    if (dfl_fmt == Py_None || dfl_fmt == NULL) {
        /** Set to 0 if None or NULL */
        dfl_fmt = pycbc_IntFromL(PYCBC_FMT_JSON);

    } else {
        Py_INCREF(dfl_fmt); /* later decref */
    }

    rv = Bucket_set_format(self, dfl_fmt, NULL);
    Py_XDECREF(dfl_fmt);
    if (rv == -1) {
        return rv;
    }

    /** Set the transcoder */
    if (tc && Bucket_set_transcoder(self, tc, NULL) == -1) {
        return -1;
    }

#if defined(WITH_THREAD)
    if (!self->unlock_gil) {
        self->lockmode = PYCBC_LOCKMODE_NONE;
    }

    if (self->lockmode != PYCBC_LOCKMODE_NONE) {
        self->lock = PyThread_allocate_lock();
    }
#else
    self->unlock_gil = 0;
    self->lockmode = PYCBC_LOCKMODE_NONE;
#endif

    err = lcb_create(&self->instance, &create_opts);
    if (err != LCB_SUCCESS) {
        self->instance = NULL;
        PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err,
                       "Couldn't create instance. Either bad "
                       "credentials/hosts/bucket names were "
                       "passed, or there was an internal error in creating the "
                       "object");
        return -1;
    }

    if (pycbc_log_handler) {
        err = lcb_cntl(self->instance, LCB_CNTL_SET, LCB_CNTL_LOGGER,
                       &pycbc_lcb_logprocs);
        if (err != LCB_SUCCESS) {
            self->instance = NULL;
            PYCBC_EXC_WRAP(PYCBC_EXC_LCBERR, err, "Couldn't create log handler");
            return -1;
        }
    }

    pycbc_callbacks_init(self->instance);
    lcb_set_cookie(self->instance, self);
    {
        const char *bucketstr;
        err = lcb_cntl(self->instance, LCB_CNTL_GET, LCB_CNTL_BUCKETNAME, &bucketstr);
        if (err == LCB_SUCCESS && bucketstr != NULL) {
            self->bucket = pycbc_SimpleStringZ(bucketstr);
        }
    }
    return 0;
}
Exemplo n.º 18
0
PyObject *
pycbc_Connection__http_request(pycbc_Connection *self,
                               PyObject *args,
                               PyObject *kwargs)
{
    int rv;
    int method;
    int reqtype;
    int quiet = 0;
    unsigned short value_format = 0;
    lcb_error_t err;

    const char *body = NULL;
    PyObject *ret = NULL;
    PyObject *quiet_O = NULL;
    PyObject *fetch_headers_O = Py_False;
    pycbc_strlen_t nbody = 0;
    const char *path = NULL;
    const char *content_type = NULL;
    pycbc_HttpResult *htres;

    lcb_http_request_t htreq = NULL;
    lcb_http_cmd_t htcmd = { 0 };

    static char *kwlist[] = {
            "type", "method", "path", "content_type", "post_data",
            "response_format", "quiet", "fetch_headers", NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "iis|zz#HOO", kwlist,
                                     &reqtype,
                                     &method,
                                     &path,
                                     &content_type,
                                     &body,
                                     &nbody,
                                     &value_format,
                                     &quiet_O,
                                     &fetch_headers_O);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }
    if (quiet_O != NULL) {
        if (quiet_O == Py_None) {
            quiet = 0;
        } else {
            quiet = PyObject_IsTrue(quiet_O);
        }
    }

    htres = pycbc_httpresult_new(self);
    htres->key = pycbc_SimpleStringZ(path);
    htres->format = value_format;

    if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) {
        htres->headers = PyDict_New();
    }

    htcmd.v.v1.body = body;
    htcmd.v.v1.nbody = nbody;
    htcmd.v.v1.content_type = content_type;
    htcmd.v.v1.path = path;
    htcmd.v.v1.npath = strlen(path);
    htcmd.v.v1.method = method;


    err = lcb_make_http_request(self->instance,
                                htres,
                                reqtype,
                                &htcmd,
                                &htreq);

    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 (quiet == 0 && pycbc_httpresult_ok(htres) == 0) {
        PYCBC_EXC_WRAP_EX(htres->rc ? PYCBC_EXC_LCBERR : PYCBC_EXC_HTTP,
                          htres->rc,
                          "HTTP Request failed. Examine 'objextra' for "
                          "full result",
                          htres->key,
                          (PyObject*)htres);
        goto GT_DONE;
    }

    ret = (PyObject*)htres;
    htres = NULL;

    GT_DONE:
    Py_XDECREF(htres);
    return ret;
}
Exemplo n.º 19
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;
}
Exemplo n.º 20
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;
}
PyObject *
pycbc_Connection__http_request(pycbc_Connection *self,
                               PyObject *args,
                               PyObject *kwargs)
{
    int rv;
    int method;
    int reqtype;
    unsigned short value_format = 0;
    lcb_error_t err;

    const char *body = NULL;
    PyObject *ret = NULL;
    PyObject *quiet_O = NULL;
    PyObject *chunked_O = NULL;
    PyObject *fetch_headers_O = Py_False;
    pycbc_strlen_t nbody = 0;
    const char *path = NULL;
    const char *content_type = NULL;
    pycbc_HttpResult *htres;
    lcb_http_request_t l_htreq;

    lcb_http_cmd_t htcmd = { 0 };

    static char *kwlist[] = {
            "type", "method", "path", "content_type", "post_data",
            "response_format", "quiet", "fetch_headers",
            "chunked", NULL
    };

    rv = PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "iis|zz#HOOO", kwlist,
                                     &reqtype,
                                     &method,
                                     &path,
                                     &content_type,
                                     &body,
                                     &nbody,
                                     &value_format,
                                     &quiet_O,
                                     &fetch_headers_O,
                                     &chunked_O);
    if (!rv) {
        PYCBC_EXCTHROW_ARGS();
        return NULL;
    }

    if (-1 == pycbc_oputil_conn_lock(self)) {
        return NULL;
    }


    htres = pycbc_httpresult_new(self);
    htres->key = pycbc_SimpleStringZ(path);
    htres->format = value_format;
    htres->htflags = 0;

    if (quiet_O != NULL && quiet_O != Py_None && PyObject_IsTrue(quiet_O)) {
        htres->htflags |= PYCBC_HTRES_F_QUIET;
    }

    if (fetch_headers_O && PyObject_IsTrue(fetch_headers_O)) {
        htres->headers = PyDict_New();
    }

    if (chunked_O && PyObject_IsTrue(chunked_O)) {
        htcmd.v.v0.chunked = 1;
        htres->rctx = lcbex_vrow_create();
        htres->rctx->callback = http_vrow_callback;
        htres->rctx->user_cookie = htres;
        htres->htflags |= PYCBC_HTRES_F_CHUNKED;
    }

    htcmd.v.v1.body = body;
    htcmd.v.v1.nbody = nbody;
    htcmd.v.v1.content_type = content_type;
    htcmd.v.v1.path = path;
    htcmd.v.v1.npath = strlen(path);
    htcmd.v.v1.method = method;


    err = lcb_make_http_request(self->instance,
                                htres,
                                reqtype,
                                &htcmd,
                                &l_htreq);

    if (err != LCB_SUCCESS) {
        PYCBC_EXCTHROW_SCHED(err);
        goto GT_DONE;
    }

    htres->htreq = l_htreq;

    if (htcmd.v.v0.chunked) {
        ret = (PyObject*)htres;
        htres = NULL;
        goto GT_DONE;
    }

    self->nremaining++;
    err = pycbc_oputil_wait_common(self);

    if (err != LCB_SUCCESS) {
        self->nremaining--;
        PYCBC_EXCTHROW_WAIT(err);
        goto GT_DONE;
    }

    if (maybe_raise(htres)) {
        goto GT_DONE;
    }

    ret = (PyObject*)htres;
    htres = NULL;

    GT_DONE:
    Py_XDECREF(htres);
    pycbc_oputil_conn_unlock(self);
    return ret;
}