Esempio n. 1
0
LIBCOUCHBASE_API
lcb_error_t
lcb_cbflush3(lcb_t instance, const void *cookie, const lcb_CMDBASE *cmd)
{
    lcb_http_request_t htr;
    lcb_CMDHTTP htcmd = { 0 };
    lcb_string urlpath;
    lcb_error_t rc;

    (void)cmd;

    lcb_string_init(&urlpath);
    lcb_string_appendz(&urlpath, "/pools/default/buckets/");
    lcb_string_appendz(&urlpath, LCBT_SETTING(instance, bucket));
    lcb_string_appendz(&urlpath, "/controller/doFlush");


    htcmd.type = LCB_HTTP_TYPE_MANAGEMENT;
    htcmd.method = LCB_HTTP_METHOD_POST;
    htcmd.reqhandle = &htr;
    LCB_CMD_SET_KEY(&htcmd, urlpath.base, urlpath.nused);

    rc = lcb_http3(instance, cookie, &htcmd);
    lcb_string_release(&urlpath);

    if (rc != LCB_SUCCESS) {
        return rc;
    }
    lcb_htreq_setcb(htr, flush_cb);
    return LCB_SUCCESS;
}
Esempio n. 2
0
// remove($id {, $cas, $groupid}) : MetaDoc
PHP_METHOD(Bucket, remove)
{
    bucket_object *data = PCBC_PHP_THISOBJ();
    int ii, ncmds, nscheduled;
    pcbc_pp_state pp_state;
    pcbc_pp_id id;
    opcookie *cookie;
    zval *zcas, *zgroupid;
    lcb_error_t err;

    // Note that groupid is experimental here and should not be used.
    if (pcbc_pp_begin(ZEND_NUM_ARGS() TSRMLS_CC, &pp_state, "id||cas,groupid",
                      &id, &zcas, &zgroupid) != SUCCESS)
    {
        throw_pcbc_exception("Invalid arguments.", LCB_EINVAL);
        RETURN_NULL();
    }

    ncmds = pcbc_pp_keycount(&pp_state);
    cookie = opcookie_init();

    nscheduled = 0;
    for (ii = 0; pcbc_pp_next(&pp_state); ++ii) {
        lcb_CMDREMOVE cmd = {0};

        PCBC_CHECK_ZVAL_STRING(zcas, "cas must be a string");
        PCBC_CHECK_ZVAL_STRING(zgroupid, "groupid must be a string");

        LCB_CMD_SET_KEY(&cmd, id.str, id.len);
        if (zcas) {
            cmd.cas = cas_decode(zcas TSRMLS_CC);
        }
        if (zgroupid) {
            LCB_KREQ_SIMPLE(&cmd._hashkey, Z_STRVAL_P(zgroupid), Z_STRLEN_P(zgroupid));
        }

        err = lcb_remove3(data->conn->lcb, cookie, &cmd);
        if (err != LCB_SUCCESS) {
            break;
        }
        nscheduled++;
    }
    pcbc_assert_number_of_commands("remove", nscheduled, ncmds);

    if (nscheduled) {
        lcb_wait(data->conn->lcb);

        err = proc_remove_results(data, return_value,
                                  cookie, pcbc_pp_ismapped(&pp_state) TSRMLS_CC);
    }

    opcookie_destroy(cookie);

    if (err != LCB_SUCCESS) {
        throw_lcb_exception(err);
    }
}
static void get_encrypted(lcb_t instance, const char *key)
{
    lcb_CMDGET cmd = {};
    lcb_error_t err;
    LCB_CMD_SET_KEY(&cmd, key, strlen(key));
    printf("KEY:    %s\n", key);
    err = lcb_get3(instance, NULL, &cmd);
    if (err != LCB_SUCCESS) {
        die(instance, "Couldn't schedule get operation", err);
    }
    lcb_wait(instance);
}
static int
chain_endure(PLCB_t *obj, AV *resobj, const lcb_RESPSTORE *resp)
{
    lcb_MULTICMD_CTX *mctx = NULL;
    lcb_CMDENDURE dcmd = { 0 };
    lcb_durability_opts_t dopts = { 0 };
    char persist_to = 0, replicate_to = 0;
    lcb_error_t err = LCB_SUCCESS;
    SV *optsv;

    optsv = *av_fetch(resobj, PLCB_RETIDX_OPTIONS, 1);
    if (!SvIOK(optsv)) {
        return 0;
    }

    PLCB_GETDURABILITY(SvUVX(optsv), persist_to, replicate_to);
    if (persist_to == 0 && replicate_to == 0) {
        return 0;
    }
    if (persist_to < 0 || replicate_to < 0) {
        dopts.v.v0.cap_max = 1;
    }

    dopts.v.v0.persist_to = persist_to;
    dopts.v.v0.replicate_to = replicate_to;
    LCB_CMD_SET_KEY(&dcmd, resp->key, resp->nkey);
    dcmd.cas = resp->cas;

    mctx = lcb_endure3_ctxnew(obj->instance, &dopts, &err);
    if (mctx == NULL) {
        plcb_doc_set_err(obj, resobj, err);
        return 0;
    }

    err = mctx->addcmd(mctx, (lcb_CMDBASE *)&dcmd);
    if (err != LCB_SUCCESS) {
        mctx->fail(mctx);
        return 0;
    }

    lcb_sched_enter(obj->instance);
    err = mctx->done(mctx, resp->cookie);
    if (err != LCB_SUCCESS) {
        plcb_doc_set_err(obj, resobj, err);
        return 0;
    }

    lcb_sched_leave(obj->instance);
    return 1;
}
Esempio n. 5
0
static void
key_from_so(plcb_SINGLEOP *so, lcb_CMDBASE *cmd)
{
    const char *key = NULL;
    STRLEN nkey = 0;

    SV **tmpsv = av_fetch(so->docav, PLCB_RETIDX_KEY, 0);
    if (so->cmdbase == PLCB_CMD_STATS) {
        if (!tmpsv) {
            return;
        }
        key = SvPV(*tmpsv, nkey);
    } else {
        if (tmpsv == NULL) {
            die("Cannot pass document without key");
        }
        plcb_get_str_or_die(*tmpsv, key, nkey, "Invalid key");
    }

    LCB_CMD_SET_KEY(cmd, key, nkey);
}
Esempio n. 6
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;
}
static void
dur_chain2(pycbc_Bucket *conn,
    pycbc_MultiResult *mres,
    pycbc_OperationResult *res, int cbtype, const lcb_RESPBASE *resp)
{
    lcb_error_t err;
    lcb_durability_opts_t dopts = { 0 };
    lcb_CMDENDURE cmd = { 0 };
    lcb_MULTICMD_CTX *mctx = NULL;
    int is_delete = cbtype == LCB_CALLBACK_REMOVE;

    res->rc = resp->rc;
    if (resp->rc == LCB_SUCCESS) {
        const lcb_MUTATION_TOKEN *mutinfo = lcb_resp_get_mutation_token(cbtype, resp);
        Py_XDECREF(res->mutinfo);

        if (mutinfo && LCB_MUTATION_TOKEN_ISVALID(mutinfo)) {
            /* Create the mutation token tuple: (vb,uuid,seqno) */
            res->mutinfo = Py_BuildValue("HKKO",
                LCB_MUTATION_TOKEN_VB(mutinfo),
                LCB_MUTATION_TOKEN_ID(mutinfo),
                LCB_MUTATION_TOKEN_SEQ(mutinfo),
                conn->bucket);
        } else {
            Py_INCREF(Py_None);
            res->mutinfo = Py_None;
        }
        res->cas = resp->cas;
    }

    /** For remove, we check quiet */
    maybe_push_operr(mres, (pycbc_Result*)res, resp->rc, is_delete ? 1 : 0);

    if ((mres->mropts & PYCBC_MRES_F_DURABILITY) == 0 || resp->rc != LCB_SUCCESS) {
        operation_completed(conn, mres);
        CB_THR_BEGIN(conn);
        return;
    }

    if (conn->dur_testhook && conn->dur_testhook != Py_None) {
        invoke_endure_test_notification(conn, (pycbc_Result *)res);
    }

    /** Setup global options */
    dopts.v.v0.persist_to = mres->dur.persist_to;
    dopts.v.v0.replicate_to = mres->dur.replicate_to;
    dopts.v.v0.timeout = conn->dur_timeout;
    dopts.v.v0.check_delete = is_delete;
    if (mres->dur.persist_to < 0 || mres->dur.replicate_to < 0) {
        dopts.v.v0.cap_max = 1;
    }

    lcb_sched_enter(conn->instance);
    mctx = lcb_endure3_ctxnew(conn->instance, &dopts, &err);
    if (mctx == NULL) {
        goto GT_DONE;
    }

    cmd.cas = resp->cas;
    LCB_CMD_SET_KEY(&cmd, resp->key, resp->nkey);
    err = mctx->addcmd(mctx, (lcb_CMDBASE*)&cmd);
    if (err != LCB_SUCCESS) {
        goto GT_DONE;
    }

    err = mctx->done(mctx, mres);
    if (err == LCB_SUCCESS) {
        mctx = NULL;
        lcb_sched_leave(conn->instance);
    }

    GT_DONE:
    if (mctx) {
        mctx->fail(mctx);
    }
    if (err != LCB_SUCCESS) {
        res->rc = err;
        maybe_push_operr(mres, (pycbc_Result*)res, err, 0);
        operation_completed(conn, mres);

    }

    CB_THR_BEGIN(conn);
}
/**
 * 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;
}
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;
}
Esempio n. 10
0
/** Observe stuff */
static void
handle_dur_storecb(mc_PIPELINE *pl, mc_PACKET *pkt,
    lcb_error_t err, const void *arg)
{
    lcb_RESPCALLBACK cb;
    lcb_RESPSTOREDUR resp = { 0 };
    lcb_CMDENDURE dcmd = { 0 };
    DURSTORECTX *dctx = (DURSTORECTX *)pkt->u_rdata.exdata;
    lcb_MULTICMD_CTX *mctx;
    lcb_durability_opts_t opts = { 0 };
    const lcb_RESPSTORE *sresp = (const lcb_RESPSTORE *)arg;

    if (err != LCB_SUCCESS) {
        goto GT_BAIL;
    }
    if (sresp->rc != LCB_SUCCESS) {
        err = sresp->rc;
        goto GT_BAIL;
    }

    resp.store_ok = 1;
    LCB_CMD_SET_KEY(&dcmd, sresp->key, sresp->nkey);
    dcmd.cas = sresp->cas;

    if (LCB_SYNCTOKEN_ISVALID(&sresp->synctoken)) {
        dcmd.synctoken = &sresp->synctoken;
    }

    /* Set the options.. */
    opts.v.v0.persist_to = dctx->persist_to;
    opts.v.v0.replicate_to = dctx->replicate_to;

    mctx = lcb_endure3_ctxnew(dctx->instance, &opts, &err);
    if (mctx == NULL) {
        goto GT_BAIL;
    }

    lcbdurctx_set_durstore(mctx, 1);
    err = mctx->addcmd(mctx, (lcb_CMDBASE*)&dcmd);
    if (err != LCB_SUCCESS) {
        mctx->fail(mctx);
        goto GT_BAIL;
    }
    lcb_sched_enter(dctx->instance);
    err = mctx->done(mctx, sresp->cookie);
    lcb_sched_leave(dctx->instance);

    if (err == LCB_SUCCESS) {
        /* Everything OK? */
        free(dctx);
        return;
    }

    GT_BAIL:
    {
        lcb_RESPENDURE dresp = { 0 };
        resp.key = sresp->key;
        resp.nkey = sresp->nkey;
        resp.cookie = sresp->cookie;
        resp.rc = err;
        resp.dur_resp = &dresp;
        cb = lcb_find_callback(dctx->instance, LCB_CALLBACK_STOREDUR);
        cb(dctx->instance, LCB_CALLBACK_STOREDUR, (const lcb_RESPBASE*)&resp);
        free(dctx);
    }

    (void)pl;
}
Esempio n. 11
0
LIBCOUCHBASE_API
lcb_error_t
lcb_n1ql_query(lcb_t instance, const void *cookie, const lcb_CMDN1QL *cmd)
{
    lcb_CMDHTTP htcmd = { 0 };
    lcb_error_t err;
    N1QLREQ *req = NULL;

    if (cmd->query == NULL || cmd->nquery == 0 ||
            cmd->callback == NULL || cmd->content_type == NULL) {
        return LCB_EINVAL;
    }
    htcmd.body = cmd->query;
    htcmd.nbody = cmd->nquery;
    htcmd.content_type = cmd->content_type;
    htcmd.method = LCB_HTTP_METHOD_POST;
    if (cmd->host) {
        htcmd.type = LCB_HTTP_TYPE_RAW;
        LCB_CMD_SET_KEY(&htcmd, QUERY_PATH, strlen(QUERY_PATH));
        htcmd.host = cmd->host;
        htcmd.username = LCBT_SETTING(instance, bucket);
        htcmd.password = LCBT_SETTING(instance, password);
    } else {
        htcmd.type = LCB_HTTP_TYPE_N1QL;
    }

    htcmd.cmdflags = LCB_CMDHTTP_F_STREAM;
    req = calloc(1, sizeof(*req));
    if (!req) {
        err = LCB_CLIENT_ENOMEM; goto GT_DESTROY;
    }

    req->callback = cmd->callback;
    req->cookie = cookie;
    req->instance = instance;
    req->parser = lcbjsp_create(LCBJSP_MODE_N1QL);

    if (!req->parser) {
        err = LCB_CLIENT_ENOMEM; goto GT_DESTROY;
    }
    req->parser->data = req;
    req->parser->callback = row_callback;

    htcmd.reqhandle = &req->htreq;
    err = lcb_http3(instance, req, &htcmd);
    if (err != LCB_SUCCESS) {
        goto GT_DESTROY;
    }

    lcb_htreq_setcb(req->htreq, chunk_callback);
    if (cmd->handle) {
        *cmd->handle = req;
    }
    return LCB_SUCCESS;

    GT_DESTROY:
    if (req) {
        req->callback = NULL;
        destroy_req(req);
    }
    return err;
}