Couchbase

 view release on metacpan or  search on metacpan

xs/Couchbase.xs  view on Meta::CPAN

    #define _free_cv(fld) if (object->fld) { SvREFCNT_dec(object->fld); object->fld = NULL; }
    _free_cv(cv_serialize); _free_cv(cv_deserialize);
    _free_cv(cv_jsonenc); _free_cv(cv_jsondec);
    _free_cv(cv_customenc); _free_cv(cv_customdec);
    #undef _free_cv
}

/*Construct a new libcouchbase object*/
static SV *
PLCB_construct(const char *pkg, HV *hvopts)
{
    lcb_t instance;
    lcb_error_t err;
    struct lcb_create_st cr_opts = { 0 };

    SV *blessed_obj;
    SV *iops_impl = NULL;
    SV *conncb = NULL;

    PLCB_t *object;
    plcb_OPTION options[] = {
        PLCB_KWARG("connstr", CSTRING, &cr_opts.v.v3.connstr),
        PLCB_KWARG("password", CSTRING, &cr_opts.v.v3.passwd),
        PLCB_KWARG("io", SV, &iops_impl),
        PLCB_KWARG("on_connect", CV, &conncb),
        { NULL }
    };

    cr_opts.version = 3;
    plcb_extract_args((SV*)hvopts, options);

    if (iops_impl && SvTYPE(iops_impl) != SVt_NULL) {
        plcb_IOPROCS *ioprocs;
        /* Validate */
        if (!sv_derived_from(iops_impl, PLCB_IOPROCS_CLASS)) {
            die("io must be a valid " PLCB_IOPROCS_CLASS);
        }
        if (!conncb) {
            die("Connection callback must be specified in async mode");
        }
        ioprocs = NUM2PTR(plcb_IOPROCS* , SvIV(SvRV(iops_impl)));
        cr_opts.v.v3.io = ioprocs->iops_ptr;
    }

    err = lcb_create(&instance, &cr_opts);

    if (!instance) {
        die("Failed to create instance: %s", lcb_strerror(NULL, err));
    }

    Newxz(object, 1, PLCB_t);
    lcb_set_cookie(instance, object);
    object->instance = instance;

    if (iops_impl) {
        object->ioprocs = newRV_inc(SvRV(iops_impl));
        object->conncb = newRV_inc(SvRV(conncb));
        object->async = 1;
    }

    plcb_callbacks_setup(object);

    #define get_stash_assert(stashname, target) \
        if (! (object->target = gv_stashpv(stashname, 0)) ) { \
            die("Couldn't load '%s'", stashname); \
        }

    get_stash_assert(PLCB_RET_CLASSNAME, ret_stash);
    get_stash_assert(PLCB_OPCTX_CLASSNAME, opctx_sync_stash);
    get_stash_assert(PLCB_VIEWHANDLE_CLASS, view_stash);
    get_stash_assert(PLCB_N1QLHANDLE_CLASS, n1ql_stash);

    blessed_obj = newSV(0);
    sv_setiv(newSVrv(blessed_obj, PLCB_BKT_CLASSNAME), PTR2IV(object));

    object->selfobj = SvRV(blessed_obj);
    return blessed_obj;
}

static int
PLCB_connect(PLCB_t *object)
{
    lcb_error_t err;
    lcb_t instance = object->instance;

    if (object->connected) {
        warn("Already connected");
        return 1;

    } else {
        if ((err = lcb_connect(instance)) != LCB_SUCCESS) {
            goto GT_ERR;
        }
        if (object->async) {
            return 0;
        }

        lcb_wait(instance);
        if ((err = lcb_get_bootstrap_status(instance)) != LCB_SUCCESS) {
            goto GT_ERR;
        }
        object->connected = 1;
        return 1;
    }

    GT_ERR:
    die("Couldn't connect: 0x%x (%s)", err, lcb_strerror(NULL, err));
    return 0;
}

static void
get_converter_pointers(PLCB_t *object, int type, SV ***cv_encode, SV ***cv_decode)
{
    if (type == PLCB_CONVERTERS_CUSTOM) {
        *cv_encode = &object->cv_customenc;
        *cv_decode = &object->cv_customdec;
    } else if (type == PLCB_CONVERTERS_JSON) {
        *cv_encode = &object->cv_jsonenc;
        *cv_decode = &object->cv_jsondec;
    } else if (type == PLCB_CONVERTERS_STORABLE) {
        *cv_encode = &object->cv_serialize;



( run in 1.596 second using v1.01-cache-2.11-cpan-d8267643d1d )