Esempio n. 1
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);
    }
}
Esempio n. 2
0
LIBCOUCHBASE_API
lcb_error_t lcb_observe(lcb_t instance,
    const void *command_cookie, lcb_size_t num,
    const lcb_observe_cmd_t *const *items)
{
    unsigned ii;
    lcb_error_t err;
    lcb_MULTICMD_CTX *mctx;

    lcb_sched_enter(instance);

    mctx = lcb_observe3_ctxnew(instance);
    if (mctx == NULL) {
        return LCB_CLIENT_ENOMEM;
    }

    for (ii = 0; ii < num; ii++) {
        lcb_CMDOBSERVE cmd = { 0 };
        const lcb_observe_cmd_t *src = items[ii];
        if (src->version == 1 && (src->v.v1.options & LCB_OBSERVE_MASTER_ONLY)) {
            cmd.cmdflags |= LCB_CMDOBSERVE_F_MASTER_ONLY;
        }
        LCB_KREQ_SIMPLE(&cmd.key, src->v.v0.key, src->v.v0.nkey);
        LCB_KREQ_SIMPLE(&cmd._hashkey, src->v.v0.hashkey, src->v.v0.nhashkey);

        err = mctx->addcmd(mctx, (lcb_CMDBASE *)&cmd);
        if (err != LCB_SUCCESS) {
            mctx->fail(mctx);
            return err;
        }
    }
    lcb_sched_enter(instance);
    mctx->done(mctx, command_cookie);
    lcb_sched_leave(instance);
    SYNCMODE_INTERCEPT(instance)
}
Esempio n. 3
0
/**
 * Schedules a single sweep of observe requests.
 */
static void poll_once(lcb_DURSET *dset)
{
    unsigned ii, n_added = 0;
    lcb_error_t err;
    lcb_MULTICMD_CTX *mctx = NULL;

    /**
     * We should never be called while an 'iter' operation is still
     * in progress
     */
    lcb_assert(dset->waiting == 0);
    dset_ref(dset);
    mctx = lcb_observe_ctx_dur_new(dset->instance);
    if (!mctx) {
        err = LCB_CLIENT_ENOMEM;
        goto GT_ERR;
    }

    for (ii = 0; ii < dset->nentries; ii++) {
        lcb_CMDOBSERVE cmd = { 0 };
        struct lcb_durability_entry_st *ent = dset->entries + ii;
        if (ent->done) {
            continue;
        }

        /* reset all the per-iteration fields */
        RESFLD(ent, persisted_master) = 0;
        RESFLD(ent, exists_master) = 0;
        RESFLD(ent, npersisted) = 0;
        RESFLD(ent, nreplicated) = 0;
        RESFLD(ent, cas) = 0;
        RESFLD(ent, rc) = LCB_SUCCESS;

        LCB_KREQ_SIMPLE(&cmd.key, RESFLD(ent, key), RESFLD(ent, nkey));
        cmd.hashkey = ent->hashkey;

        err = mctx->addcmd(mctx, (lcb_CMDBASE *)&cmd);
        if (err != LCB_SUCCESS) {
            goto GT_ERR;
        }
        n_added ++;
    }

    lcb_assert(n_added == dset->nremaining);

    if (n_added) {
        lcb_sched_enter(dset->instance);
        mctx->done(mctx, dset);
        lcb_sched_leave(dset->instance);
    }

    GT_ERR:
    if (err != LCB_SUCCESS) {
        if (mctx) {
            mctx->fail(mctx);
        }

        for (ii = 0; ii < dset->nentries; ii++) {
            lcb_DURITEM *ent = dset->entries + ii;
            if (ent->done) {
                continue;
            }
            RESFLD(ent, rc) = err;
            ent_set_resdone(ent);
        }

    } else {
        dset->waiting = 1;
        dset_ref(dset);
    }

    if (dset->waiting && n_added) {
        lcb_uint32_t us_now = (lcb_uint32_t)(gethrtime() / 1000);
        lcb_uint32_t us_tmo;
        if (dset->us_timeout > us_now) {
            us_tmo = dset->us_timeout - us_now;
        } else {
            us_tmo = 1;
        }
        timer_schedule(dset, us_tmo, STATE_TIMEOUT);
    } else {
        purge_entries(dset, LCB_ERROR);
    }

    dset_unref(dset);
}