DBD-PgSPI

 view release on metacpan or  search on metacpan

PgSPI.xs  view on Meta::CPAN

    CODE:
    warn("rollback ineffective in PgSPI");
    ST(0) = &PL_sv_yes;


void
disconnect(dbh)
    SV *	dbh
    CODE:
    D_imp_dbh(dbh);
    if ( !DBIc_ACTIVE(imp_dbh) ) {
        XSRETURN_YES;
    }
    /* pre-disconnect checks and tidy-ups */
    if (DBIc_CACHED_KIDS(imp_dbh)) {
        SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh));
        DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
    }
    /* Check for disconnect() being called whilst refs to cursors	*/
    /* still exists. This possibly needs some more thought.		*/
    if (DBIc_ACTIVE_KIDS(imp_dbh) && DBIc_WARN(imp_dbh) && !PL_dirty) {
        char *plural = (DBIc_ACTIVE_KIDS(imp_dbh)==1) ? "" : "s";
        warn("disconnect(%s) invalidates %d active statement%s. %s",
            SvPV(dbh,PL_na), (int)DBIc_ACTIVE_KIDS(imp_dbh), plural,
            "Either destroy statement handles or call finish on them before disconnecting.");
    }
    ST(0) = dbd_db_disconnect(dbh, imp_dbh) ? &PL_sv_yes : &PL_sv_no;


void
STORE(dbh, keysv, valuesv)
    SV *	dbh
    SV *	keysv
    SV *	valuesv
    CODE:
    D_imp_dbh(dbh);
    ST(0) = &PL_sv_yes;
    if (!dbd_db_STORE_attrib(dbh, imp_dbh, keysv, valuesv)) {
        if (!DBIS->set_attr(dbh, keysv, valuesv)) {
            ST(0) = &PL_sv_no;
        }
    }


void
FETCH(dbh, keysv)
    SV *	dbh
    SV *	keysv
    CODE:
    D_imp_dbh(dbh);
    SV *valuesv = dbd_db_FETCH_attrib(dbh, imp_dbh, keysv);
    if (!valuesv) {
        valuesv = DBIS->get_attr(dbh, keysv);
    }
    ST(0) = valuesv;	/* dbd_db_FETCH_attrib did sv_2mortal	*/


void
DESTROY(dbh)
    SV *	dbh
    PPCODE:
    D_imp_dbh(dbh);
    ST(0) = &PL_sv_yes;
    if (!DBIc_IMPSET(imp_dbh)) {	/* was never fully set up	*/
        if (DBIc_WARN(imp_dbh) && !PL_dirty && dbis->debug >= 2) {
            warn("Database handle %s DESTROY ignored - never set up", SvPV(dbh,PL_na));
        }
    }
    else {
	/* pre-disconnect checks and tidy-ups */
        if (DBIc_CACHED_KIDS(imp_dbh)) {
            SvREFCNT_dec(DBIc_CACHED_KIDS(imp_dbh));
            DBIc_CACHED_KIDS(imp_dbh) = Nullhv;
        }
        if (DBIc_IADESTROY(imp_dbh)) { /* want's ineffective destroy    */
            DBIc_ACTIVE_off(imp_dbh);
        }
        if (DBIc_ACTIVE(imp_dbh)) {
            if (DBIc_WARN(imp_dbh) && (!PL_dirty || dbis->debug >= 3)) {
                warn("Database handle destroyed without explicit disconnect");
            }
            if (!DBIc_has(imp_dbh,DBIcf_AutoCommit)) {
                dbd_db_rollback(dbh, imp_dbh);	/* ROLLBACK! */
            }
            dbd_db_disconnect(dbh, imp_dbh);
        }
        dbd_db_destroy(dbh, imp_dbh);
    }


# -- end of DBD::PgSPI::db


# ------------------------------------------------------------
# statement interface
# ------------------------------------------------------------
MODULE = DBD::PgSPI	PACKAGE = DBD::PgSPI::st

void
_prepare(sth, statement, attribs=Nullsv)
    SV *	sth
    char *	statement
    SV *	attribs
    CODE:
    {
    D_imp_sth(sth);
    D_imp_dbh_from_sth;
    DBD_ATTRIBS_CHECK("_prepare", sth, attribs);
    if (!strncasecmp(statement, "begin",    5) ||
        !strncasecmp(statement, "end",      4) ||
        !strncasecmp(statement, "commit",   6) ||
        !strncasecmp(statement, "abort",    5) ||
        !strncasecmp(statement, "rollback", 8) ) {
        warn("please use DBI functions for transaction handling");
        ST(0) = &PL_sv_no;
    } else {
        ST(0) = dbd_st_prepare(sth, imp_sth, statement, attribs) ? &PL_sv_yes : &PL_sv_no;
    }
    }


PgSPI.xs  view on Meta::CPAN

            DBD_ATTRIBS_CHECK("bind_param", sth, attribs);
	    /* XXX we should perhaps complain if TYPE is not SvNIOK */
            DBD_ATTRIB_GET_IV(attribs, "TYPE", 4, svp, sql_type);
        }
    }
    ST(0) = dbd_bind_ph(sth, imp_sth, param, value, sql_type, attribs, FALSE, 0) ? &PL_sv_yes : &PL_sv_no;
    }

void
execute(sth, ...)
    SV *	sth
    CODE:
    D_imp_sth(sth);
    int ret;
    if (items > 1) {
	/* Handle binding supplied values to placeholders	*/
        int i;
        SV *idx;
        imp_sth->all_params_len = 0; /* used for malloc of statement string in case we have placeholders */
        if (items-1 != DBIc_NUM_PARAMS(imp_sth)) {
            croak("execute called with %ld bind variables, %d needed", items-1, DBIc_NUM_PARAMS(imp_sth));
            XSRETURN_UNDEF;
        }
        idx = sv_2mortal(newSViv(0));
        for(i=1; i < items ; ++i) {
            sv_setiv(idx, i);
            if (!dbd_bind_ph(sth, imp_sth, idx, ST(i), 0, Nullsv, FALSE, 0)) {
		XSRETURN_UNDEF;	/* dbd_bind_ph already registered error	*/
            }
        }
    }
    ret = dbd_st_execute(sth, imp_sth);
    /* remember that dbd_st_execute must return <= -2 for error	*/
    if (ret == 0) {		/* ok with no rows affected	*/
        XST_mPV(0, "0E0");	/* (true but zero)		*/
    }
    else if (ret < -1) {	/* -1 == unknown number of rows	*/
        XST_mUNDEF(0);		/* <= -2 means error   		*/
    }
    else {
        XST_mIV(0, ret);	/* typically 1, rowcount or -1	*/
    }


void
fetchrow_arrayref(sth)
    SV *	sth
    ALIAS:
        fetch = 1
    CODE:
    D_imp_sth(sth);
    AV *av = dbd_st_fetch(sth, imp_sth);
    ST(0) = (av) ? sv_2mortal(newRV_inc((SV *)av)) : &PL_sv_undef;


void
fetchrow_array(sth)
    SV *	sth
    ALIAS:
        fetchrow = 1
    PPCODE:
    D_imp_sth(sth);
    AV *av;
    av = dbd_st_fetch(sth, imp_sth);
    if (av) {
        int num_fields = AvFILL(av)+1;
        int i;
        EXTEND(sp, num_fields);
        for(i=0; i < num_fields; ++i) {
            PUSHs(AvARRAY(av)[i]);
        }
    }


void
finish(sth)
    SV *	sth
    CODE:
    D_imp_sth(sth);
    D_imp_dbh_from_sth;
    if (!DBIc_ACTIVE(imp_dbh)) {
	/* Either an explicit disconnect() or global destruction	*/
	/* has disconnected us from the database. Finish is meaningless	*/
	/* XXX warn */
        XSRETURN_YES;
    }
    if (!DBIc_ACTIVE(imp_sth)) {
	/* No active statement to finish	*/
        XSRETURN_YES;
    }
    ST(0) = dbd_st_finish(sth, imp_sth) ? &PL_sv_yes : &PL_sv_no;


void
STORE(sth, keysv, valuesv)
    SV *	sth
    SV *	keysv
    SV *	valuesv
    CODE:
    D_imp_sth(sth);
    ST(0) = &PL_sv_yes;
    if (!dbd_st_STORE_attrib(sth, imp_sth, keysv, valuesv)) {
        if (!DBIS->set_attr(sth, keysv, valuesv)) {
            ST(0) = &PL_sv_no;
        }
    }


# FETCH renamed and ALIAS'd to avoid case clash on VMS :-(
void
FETCH_attrib(sth, keysv)
    SV *	sth
    SV *	keysv
    ALIAS:
    FETCH = 1
    CODE:
    D_imp_sth(sth);
    SV *valuesv = dbd_st_FETCH_attrib(sth, imp_sth, keysv);
    if (!valuesv) {
        valuesv = DBIS->get_attr(sth, keysv);
    }
    ST(0) = valuesv;	/* dbd_st_FETCH_attrib did sv_2mortal	*/


void
DESTROY(sth)
    SV *	sth
    PPCODE:
    D_imp_sth(sth);
    ST(0) = &PL_sv_yes;
    if (!DBIc_IMPSET(imp_sth)) {	/* was never fully set up	*/
        if (DBIc_WARN(imp_sth) && !PL_dirty && dbis->debug >= 2) {
            warn("Statement handle %s DESTROY ignored - never set up", SvPV(sth,PL_na));
        }
    }
    else {
        if (DBIc_IADESTROY(imp_sth)) { /* want's ineffective destroy    */
            DBIc_ACTIVE_off(imp_sth);
        }
        if (DBIc_ACTIVE(imp_sth)) {
            dbd_st_finish(sth, imp_sth);
        }
        dbd_st_destroy(sth, imp_sth);
    }


# end of PgSPI.xs



( run in 0.491 second using v1.01-cache-2.11-cpan-71847e10f99 )