Author: timbo
Date: Wed Jun 13 06:11:35 2007
New Revision: 9646

Modified:
   dbi/trunk/Changes
   dbi/trunk/lib/DBI/Profile.pm
   dbi/trunk/t/01basics.t
   dbi/trunk/t/40profile.t

Log:
Changed t/01basic.t to warn instead of failing when it detects
a problem with Math::BigInt (some recent versions have been buggy).
Added as_node_path_list() method.


Modified: dbi/trunk/Changes
==============================================================================
--- dbi/trunk/Changes   (original)
+++ dbi/trunk/Changes   Wed Jun 13 06:11:35 2007
@@ -47,6 +47,8 @@
   Fixed t/86gofer_fail tests to be less likely to fail falsely.
 
   Corrected timeout example in docs thanks to Egmont Koblinger.
+  Changed t/01basic.t to warn instead of failing when it detects
+    a problem with Math::BigInt (some recent versions have been buggy).
 
   Added support for !Time and !Time~N to DBI::Profile Path.
   Added extra trace info to connect_cached thanks to Walery Studennikov.
@@ -55,6 +57,7 @@
 
   DBI::Profile changes:
     Don't profile DESTROY during global destruction.
+    Added as_node_path_list() method.
   DBI::ProfileDumper changes:
     Don't write file if there's no profile data.
     Uses full natural precision when saving data (was using %.6f)

Modified: dbi/trunk/lib/DBI/Profile.pm
==============================================================================
--- dbi/trunk/lib/DBI/Profile.pm        (original)
+++ dbi/trunk/lib/DBI/Profile.pm        Wed Jun 13 06:11:35 2007
@@ -440,6 +440,45 @@
 to the same merged profile data tree.
 
 
+=head1 PROFILE OBJECT METHODS
+
+=head2 format
+
+See L</REPORTING>.
+
+=head2 as_node_path_list
+
+  @ary = $dbh->{Profile}->as_node_path_list();
+  @ary = $dbh->{Profile}->as_node_path_list($node, $path);
+
+Returns the collected data ($dbh->{Profile}{Data}) restructured into a list of
+array refs, one for each leaf node in the Data tree. This 'flat' structure is
+often much simpler for applications to work with.
+
+The first element of each array ref is a reference to the leaf node.
+The remaining elements are the 'path' through the data tree to that node.
+
+For example, given a data tree like this:
+
+    {key1a}{key2a}[node1]
+    {key1a}{key2b}[node2]
+    {key1b}{key2a}{key3a}[node3]
+
+The as_node_path_list() method  will return this list:
+
+    [ [node1], 'key1a', 'key2a' ]
+    [ [node2], 'key1a', 'key2b' ]
+    [ [node3], 'key1b', 'key2a', 'key3a' ]
+
+The nodes are ordered by key, depth-first.
+
+The $node argument can be used to focus on a sub-tree.
+If not specified it defaults to $dbh->{Profile}{Data}.
+
+The $path argument can be used to specify a list of path elements that will be
+added to each element of the returned list. If not specified it defaults to a a
+ref to an empty array.
+
 =head1 CUSTOM DATA MANIPULATION
 
 Recall that C<$h->{Profile}->{Data}> is a reference to the collected data.
@@ -679,6 +718,31 @@
 }
 
 
+sub as_node_path_list {
+    my ($self, $node, $path) = @_;
+    # convert the tree into an array of arrays
+    # from 
+    #   {key1a}{key2a}[node1]
+    #   {key1a}{key2b}[node2]
+    #   {key1b}{key2a}{key3a}[node3]
+    # to
+    #   [ [node1], 'key1a', 'key2a' ]
+    #   [ [node2], 'key1a', 'key2b' ]
+    #   [ [node3], 'key1b', 'key2a', 'key3a' ]
+
+    $node ||= $self->{Data} or return;
+    $path ||= [];
+    if (ref $node eq 'HASH') {    # recurse
+        $path = [ @$path, undef ];
+        return map {
+            $path->[-1] = $_;
+            ($node->{$_}) ? $self->as_node_path_list($node->{$_}, $path) : ()
+        } sort keys %$node;
+    }
+    return [ $node, @$path ];
+}
+
+
 sub format {
     my $self = shift;
     my $class = ref($self) || $self;

Modified: dbi/trunk/t/01basics.t
==============================================================================
--- dbi/trunk/t/01basics.t      (original)
+++ dbi/trunk/t/01basics.t      Wed Jun 13 06:11:35 2007
@@ -233,8 +233,19 @@
        if $DBI::PurePerl && !eval { require Math::BigInt; require_version 
Math::BigInt 1.56 };
     skip("Math::BigInt $Math::BigInt::VERSION broken",2)
        if $DBI::PurePerl && $Math::BigInt::VERSION =~ /^1\.8[45]/;
-cmp_ok(DBI::hash("foo1",1), '==', -1263462440, '... should be -1263462440');
-cmp_ok(DBI::hash("foo2",1), '==', -1263462437, '... should be -1263462437');
+    my $bigint_vers = $Math::BigInt::VERSION || "";
+    if (!$DBI::PurePerl) {
+        cmp_ok(DBI::hash("foo1",1), '==', -1263462440);
+        cmp_ok(DBI::hash("foo2",1), '==', -1263462437);
+    }
+    else {
+        # for PurePerl we use Math::BigInt but that's often caused test 
failures that
+        # aren't DBI's fault. So we just warn (via a skip) if it's not working 
right.
+        skip("Seems like your Math::BigInt $Math::BigInt::VERSION has a bug",2)
+            unless (DBI::hash("foo1X",1) == -1263462440) && 
(DBI::hash("foo2",1) == -1263462437);
+        ok(1, "Math::BigInt $Math::BigInt::VERSION worked okay");
+        ok(1);
+    }
 }
 
 is(data_string_desc(""), "UTF8 off, ASCII, 0 characters 0 bytes");

Modified: dbi/trunk/t/40profile.t
==============================================================================
--- dbi/trunk/t/40profile.t     (original)
+++ dbi/trunk/t/40profile.t     Wed Jun 13 06:11:35 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 => 52;
+    plan tests => 54;
 }
 
 $Data::Dumper::Indent = 1;
@@ -214,23 +214,39 @@
         },
        'usrnam' => {
            '' => {
-                   'foo' => { },
+                'foo' => { },
            },
            'select name from .' => {
-                   'foo' => {
-                       'execute' => [ 1, 0, 0, 0, 0, 0, 0 ],
-                       'fetchrow_hashref' => [ 1, 0, 0, 0, 0, 0, 0 ],
-                       'prepare' => [ 1, 0, 0, 0, 0, 0, 0 ],
-                   },
-                   'bar' => {
-                       'DESTROY' => [ 1, 0, 0, 0, 0, 0, 0 ],
-                       'finish' => [ 1, 0, 0, 0, 0, 0, 0 ],
-                   },
+                'foo' => {
+                    'execute' => [ 1, 0, 0, 0, 0, 0, 0 ],
+                    'fetchrow_hashref' => [ 1, 0, 0, 0, 0, 0, 0 ],
+                    'prepare' => [ 1, 0, 0, 0, 0, 0, 0 ],
+                },
+                'bar' => {
+                    'DESTROY' => [ 1, 0, 0, 0, 0, 0, 0 ],
+                    'finish' => [ 1, 0, 0, 0, 0, 0, 0 ],
+                },
            },
        },
     },
 } => 'DBI::Profile';
 
+$tmp = [ $dbh->{Profile}->as_node_path_list() ];
+is @$tmp, 9, 'should have 9 nodes';
+sanitize_profile_data_nodes($_->[0]) for @$tmp;
+#warn Dumper($dbh->{Profile}->{Data});
+is_deeply $tmp, [
+  [ [ 3, 0, 0, 0, 0, 0, 0 ], '', '', 'foo', 'STORE' ],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', '', 'foo', 'FETCH' ],
+  [ [ 2, 0, 0, 0, 0, 0, 0 ], 'usrnam', '', 'foo', 'STORE' ],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', '', 'foo', 'connected' ],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', 'select name from .', 'bar', 'DESTROY' 
],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', 'select name from .', 'bar', 'finish' ],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', 'select name from .', 'foo', 'execute' 
],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', 'select name from .', 'foo', 
'fetchrow_hashref' ],
+  [ [ 1, 0, 0, 0, 0, 0, 0 ], 'usrnam', 'select name from .', 'foo', 'prepare' ]
+];
+
 
 print "testing '!File', '!Caller' and their variants in Path\n";
 

Reply via email to