DBD-PgSPI
view release on metacpan or search on metacpan
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;
}
}
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 )