Author: timbo
Date: Thu Jun 14 06:20:31 2007
New Revision: 9653

Modified:
   dbi/trunk/Changes
   dbi/trunk/DBI.xs
   dbi/trunk/t/40profile.t

Log:
dbi_profile() now returns ref to relevant leaf node


Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Thu Jun 14 06:20:31 2007
@@ -56,6 +56,7 @@
   Added DBIXS_REVISION macro that drivers can use.
 
   DBI::Profile changes:
+    dbi_profile() now returns ref to relevant leaf node.
     Don't profile DESTROY during global destruction.
     Added as_node_path_list() and as_text() methods and tests.
   DBI::ProfileDumper changes:

Modified: dbi/trunk/DBI.xs
==============================================================================
--- dbi/trunk/DBI.xs    (original)
+++ dbi/trunk/DBI.xs    Thu Jun 14 06:20:31 2007
@@ -2295,7 +2295,7 @@
 }
 
 
-static void
+static SV*
 dbi_profile(SV *h, imp_xxh_t *imp_xxh, SV *statement_sv, SV *method, NV t1, NV 
t2)
 {
 #define DBIprof_MAX_PATH_ELEM  100
@@ -2324,10 +2324,10 @@
     const int parent_call_depth = DBIc_PARENT_COM(imp_xxh) ? 
DBIc_CALL_DEPTH(DBIc_PARENT_COM(imp_xxh)) : 0;
     /* Only count calls originating from the application code  */
     if (call_depth > 1 || parent_call_depth > 0)
-       return;
+       return &sv_undef;
 
     if (!DBIc_has(imp_xxh, DBIcf_Profile))
-       return;
+       return &sv_undef;
 
     method_pv = (SvTYPE(method)==SVt_PVCV)
         ? GvNAME(CvGV(method))
@@ -2335,7 +2335,7 @@
 
     /* we don't profile DESTROY during global destruction */
     if (dirty && instr(method_pv, "DESTROY"))
-        return;
+        return &sv_undef;
 
     h_hv = (HV*)SvRV(dbih_inner(aTHX_ h, "dbi_profile"));
 
@@ -2346,7 +2346,7 @@
        DBIc_set(imp_xxh, DBIcf_Profile, 0); /* disable */
        if (!dirty)
            warn("Profile attribute isn't a hash ref (%s,%ld)", 
neatsvpv(profile,0), (long)SvTYPE(profile));
-       return;
+       return &sv_undef;
     }
 
     /* statement_sv: undef = use $h->{Statement}, "" (&sv_no) = use empty 
string */
@@ -2404,7 +2404,7 @@
                 }
                 PUTBACK;
                 if (items == -2) /* this profile data was vetoed */
-                    return;
+                    return &sv_undef;
            }
             else if (SvROK(pathsv)) {
                 /* only meant for refs to scalars currently */
@@ -2476,10 +2476,10 @@
                        imp_dbh_t *imp_dbh = (DBIc_TYPE(imp_xxh) <= DBIt_DB) ? 
(imp_dbh_t*)imp_xxh : (imp_dbh_t*)DBIc_PARENT_COM(imp_xxh);
                        dbh_outer_hv = DBIc_MY_H(imp_dbh);
                        if (SvTYPE(dbh_outer_hv) != SVt_PVHV)
-                           return;     /* presumably global destruction - bail 
*/
+                           return &sv_undef;   /* presumably global 
destruction - bail */
                        dbh_inner_hv = (HV*)SvRV(dbih_inner(aTHX_ 
(SV*)dbh_outer_hv, "profile"));
                        if (SvTYPE(dbh_inner_hv) != SVt_PVHV)
-                           return;     /* presumably global destruction - bail 
*/
+                           return &sv_undef;   /* presumably global 
destruction - bail */
                    }
                    /* fetch from inner first, then outer if key doesn't exist 
*/
                    /* (yes, this is an evil premature optimization) */
@@ -2514,11 +2514,9 @@
     }
 
 
-    /* this walk-down-the-tree code should be merged into the loop above */
-    tmp = dest_node;
-    if (!SvOK(tmp)) {
+    if (!SvOK(dest_node)) {
        av = newAV();
-       sv_setsv(tmp, newRV_noinc((SV*)av));
+       sv_setsv(dest_node, newRV_noinc((SV*)av));
        av_store(av, DBIprof_COUNT,             newSViv(1));
        av_store(av, DBIprof_TOTAL_TIME,        newSVnv(ti));
        av_store(av, DBIprof_FIRST_TIME,        newSVnv(ti));
@@ -2528,6 +2526,7 @@
        av_store(av, DBIprof_LAST_CALLED,       newSVnv(t1));
     }
     else {
+        tmp = dest_node;
        if (SvROK(tmp))
            tmp = SvRV(tmp);
        if (SvTYPE(tmp) != SVt_PVAV)
@@ -2543,9 +2542,10 @@
        if (ti > SvNV(tmp)) sv_setnv(tmp, ti);
        sv_setnv( *av_fetch(av, DBIprof_LAST_CALLED, 1), t1);
     }
-    return;
+    return dest_node; /* use with caution - copy first, ie sv_mortalcopy() */
 }
 
+
 static void
 dbi_profile_merge_nodes(SV *dest, SV *increment)
 {
@@ -4159,7 +4159,7 @@
 dbi_time()
 
 
-SV *
+void
 dbi_profile(h, statement, method, t1, t2)
     SV *h
     SV *statement
@@ -4168,14 +4168,15 @@
     NV t2
     CODE:
     D_imp_xxh(h);
-    (void)cv;
-    dbi_profile(h, imp_xxh, statement,
+    SV *leaf = dbi_profile(h, imp_xxh, statement,
        SvROK(method) ? SvRV(method) : method,
        t1, t2
     );
-    RETVAL = &sv_undef;
-    OUTPUT:
-    RETVAL
+    (void)cv;
+    if (GIMME_V == G_VOID)
+        ST(0) = &sv_undef;  /* skip sv_mortalcopy if not needed */
+    else
+        ST(0) = sv_mortalcopy(leaf);
 
 
 SV *

Modified: dbi/trunk/t/40profile.t
==============================================================================
--- dbi/trunk/t/40profile.t     (original)
+++ dbi/trunk/t/40profile.t     Thu Jun 14 06:20:31 2007
@@ -22,7 +22,7 @@
     # tie methods (STORE/FETCH etc) get called different number of times
     plan skip_all => "test results assume perl >= 5.8.2"
         if $] <= 5.008001;
-    plan tests => 55;
+    plan tests => 58;
 }
 
 $Data::Dumper::Indent = 1;
@@ -97,13 +97,19 @@
 my $t1 = DBI::dbi_time() . ""; 
 my $dummy_statement = "Hi mom";
 my $dummy_methname  = "my_method_name";
-dbi_profile($dbh, $dummy_statement, $dummy_methname, $t1, $t1 + 1);
+my $leaf = dbi_profile($dbh, $dummy_statement, $dummy_methname, $t1, $t1 + 1);
 print Dumper($dbh->{Profile});
 cmp_ok(keys %{ $dbh->{Profile}{Data} }, '==', 2);
 cmp_ok(keys %{ $dbh->{Profile}{Data}{$dummy_statement} }, '==', 1);
-ok(        ref $dbh->{Profile}{Data}{$dummy_statement}{$dummy_methname}    );
+is(        ref($dbh->{Profile}{Data}{$dummy_statement}{$dummy_methname}), 
'ARRAY');
+
+ok $leaf, "should return ref to leaf node";
+is ref $leaf, 'ARRAY', "should return ref to leaf node";
 
 my $mine = $dbh->{Profile}{Data}{$dummy_statement}{$dummy_methname};
+
+is $leaf, $mine, "should return ref to correct leaf node";
+
 print "@$mine\n";
 is_deeply $mine, [ 1, 1, 1, 1, 1, $t1, $t1 ];
 

Reply via email to