DBI
view release on metacpan or search on metacpan
nima->stash = NULL;
nima->gv = NULL;
nima->my_perl = my_perl;
ima = nima;
}
#endif
ima_flags = ima->flags;
meth_type = ima->meth_type;
if (trace_level >= 9) {
PerlIO *logfp = DBILOGFP;
PerlIO_printf(logfp,"%c >> %-11s DISPATCH (%s rc%ld/%ld @%ld g%x ima%lx pid#%ld)",
(PL_dirty?'!':' '), meth_name, neatsvpv(h,0),
(long)SvREFCNT(h), (SvROK(h) ? (long)SvREFCNT(SvRV(h)) : (long)-1),
(long)items, (int)gimme, (long)ima_flags, (long)PerlProc_getpid());
PerlIO_puts(logfp, log_where(0, 0, " at ","\n", 1, (trace_level >= 3), (trace_level >= 4)));
PerlIO_flush(logfp);
}
if ( ( (is_DESTROY=(meth_type == methtype_DESTROY))) ) {
/* note that croak()'s won't propagate, only append to $@ */
keep_error = TRUE;
}
/* If h is a tied hash ref, switch to the inner ref 'behind' the tie.
This means *all* DBI methods work with the inner (non-tied) ref.
This makes it much easier for methods to access the real hash
data (without having to go through FETCH and STORE methods) and
for tie and non-tie methods to call each other.
*/
if (SvROK(h)
&& SvRMAGICAL(SvRV(h))
&& (
((mg=SvMAGIC(SvRV(h)))->mg_type == 'P')
|| ((mg=mg_find(SvRV(h),'P')) != NULL)
)
) {
if (mg->mg_obj==NULL || !SvOK(mg->mg_obj) || SvRV(mg->mg_obj)==NULL) { /* maybe global destruction */
if (trace_level >= 3)
PerlIO_printf(DBILOGFP,
"%c <> %s for %s ignored (inner handle gone)\n",
(PL_dirty?'!':' '), meth_name, neatsvpv(h,0));
XSRETURN(0);
}
/* Distinguish DESTROY of tie (outer) from DESTROY of inner ref */
/* This may one day be used to manually destroy extra internal */
/* refs if the application ceases to use the handle. */
if (is_DESTROY) {
imp_xxh = DBIh_COM(mg->mg_obj);
#ifdef DBI_USE_THREADS
if (imp_xxh && DBIc_THR_USER(imp_xxh) != my_perl) {
goto is_DESTROY_wrong_thread;
}
#endif
if (imp_xxh && DBIc_TYPE(imp_xxh) <= DBIt_DB)
clear_cached_kids(aTHX_ mg->mg_obj, imp_xxh, meth_name, trace_level);
/* XXX might be better to move this down to after call_depth has been
* incremented and then also SvREFCNT_dec(mg->mg_obj) to force an immediate
* DESTROY of the inner handle if there are no other refs to it.
* That way the inner DESTROY is properly flagged as a nested call,
* and the outer DESTROY gets profiled more accurately, and callbacks work.
*/
if (trace_level >= 3) {
PerlIO_printf(DBILOGFP,
"%c <> DESTROY(%s) ignored for outer handle (inner %s has ref cnt %ld)\n",
(PL_dirty?'!':' '), neatsvpv(h,0), neatsvpv(mg->mg_obj,0),
(long)SvREFCNT(SvRV(mg->mg_obj))
);
}
/* for now we ignore it since it'll be followed soon by */
/* a destroy of the inner hash and that'll do the real work */
/* However, we must at least modify DBIc_MY_H() as that is */
/* pointing (without a refcnt inc) to the scalar that is */
/* being destroyed, so it'll contain random values later. */
if (imp_xxh)
DBIc_MY_H(imp_xxh) = (HV*)SvRV(mg->mg_obj); /* inner (untied) HV */
XSRETURN(0);
}
h = mg->mg_obj; /* switch h to inner ref */
ST(0) = h; /* switch handle on stack to inner ref */
}
imp_xxh = dbih_getcom2(aTHX_ h, 0); /* get common Internal Handle Attributes */
if (!imp_xxh) {
if (meth_type == methtype_can) { /* ref($h)->can("foo") */
const char *can_meth = SvPV_nolen(st1);
SV *rv = &PL_sv_undef;
GV *gv = gv_fetchmethod_autoload(gv_stashsv(orig_h,FALSE), can_meth, FALSE);
if (gv && isGV(gv))
rv = sv_2mortal(newRV_inc((SV*)GvCV(gv)));
if (trace_level >= 1) {
PerlIO_printf(DBILOGFP," <- %s(%s) = %p\n", meth_name, can_meth, neatsvpv(rv,0));
}
ST(0) = rv;
XSRETURN(1);
}
if (trace_level)
PerlIO_printf(DBILOGFP, "%c <> %s for %s ignored (no imp_data)\n",
(PL_dirty?'!':' '), meth_name, neatsvpv(h,0));
if (!is_DESTROY)
warn("Can't call %s method on handle %s%s", meth_name, neatsvpv(h,0),
SvROK(h) ? " after take_imp_data()" : " (not a reference)");
XSRETURN(0);
}
if (DBIc_has(imp_xxh,DBIcf_Profile)) {
profile_t1 = dbi_time(); /* just get start time here */
}
#ifdef DBI_USE_THREADS
{
PerlInterpreter * h_perl;
is_DESTROY_wrong_thread:
h_perl = DBIc_THR_USER(imp_xxh) ;
if (h_perl != my_perl) {
/* XXX could call a 'handle clone' method here?, for dbh's at least */
if (is_DESTROY) {
if (trace_level >= 3) {
PerlIO_printf(DBILOGFP," DESTROY ignored because DBI %sh handle (%s) is owned by thread %p not current thread %p\n",
( run in 2.284 seconds using v1.01-cache-2.11-cpan-d8267643d1d )