X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FManual%2FCookbook.pod;h=9f2a8fa9b9de4910fde9f151241a039877522f49;hb=416e92f76193b3215745593cd066ff9a8e3ab1b8;hp=5a857fbb7ca3a3fed073181f0a70fafd6d10231a;hpb=1def34512e92e6b79853aceafec585080ede4960;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Manual/Cookbook.pod b/lib/DBIx/Class/Manual/Cookbook.pod index 5a857fb..9f2a8fa 100644 --- a/lib/DBIx/Class/Manual/Cookbook.pod +++ b/lib/DBIx/Class/Manual/Cookbook.pod @@ -313,9 +313,8 @@ L has now prefetched all matching data from the C table, so no additional SQL statements are executed. You now have a much more efficient query. -Note that as of L 0.04, C cannot be used with -C relationships. You will get an error along the lines of "No -accessor for prefetched ..." if you try. +Note that as of L 0.05999_01, C I be used with +C relationships. Also note that C should only be used when you know you will definitely use data from a related table. Pre-fetching related tables when you @@ -410,24 +409,22 @@ example of the recommended way to use it: my $genus = $schema->resultset('Genus')->find(12); + my $coderef2 = sub { + $genus->extinct(1); + $genus->update; + }; + my $coderef1 = sub { - my ($schema, $genus, $code) = @_; $genus->add_to_species({ name => 'troglodyte' }); $genus->wings(2); $genus->update; - $schema->txn_do($code, $genus); # Can have a nested transaction + $schema->txn_do($coderef2); # Can have a nested transaction return $genus->species; }; - my $coderef2 = sub { - my ($genus) = @_; - $genus->extinct(1); - $genus->update; - }; - my $rs; eval { - $rs = $schema->txn_do($coderef1, $schema, $genus, $coderef2); + $rs = $schema->txn_do($coderef1); }; if ($@) { # Transaction failed @@ -753,11 +750,10 @@ dumping it. For example, package My::DB::CD; sub _dumper_hook { - my $obj = shift; - return bless { - %{ $obj }, + $_[0] = bless { + %{ $_[0] }, result_source => undef, - }, ref($obj); + }, ref($_[0]); } [...] @@ -776,7 +772,6 @@ base class and set C<$Data::Dumper::Freezer> to its name and L will automagically clean up your data before printing it. See L for more information. - =head2 Retrieving a row object's Schema It is possible to get a Schema object from a row object like so, @@ -788,4 +783,77 @@ It is possible to get a Schema object from a row object like so, This can be useful when you don't want to pass around a Schema object to every method. +=head2 Profiling + +When you enable L's debugging it prints the SQL +executed as well as notifications of query completion and transaction +begin/commit. If you'd like to profile the SQL you can subclass the +L class and write your own profiling +mechanism: + + package My::Profiler; + use strict; + + use base 'DBIx::Class::Storage::Statistics'; + + use Time::HiRes qw(time); + + my $start; + + sub query_start { + my $self = shift(); + my $sql = shift(); + my $params = @_; + + print "Executing $sql: ".join(', ', @params)."\n"; + $start = time(); + } + + sub query_end { + my $self = shift(); + my $sql = shift(); + my @params = @_; + + printf("Execution took %0.4f seconds.\n", time() - $start); + $start = undef; + } + + 1; + +You can then install that class as the debugging object: + + __PACKAGE__->storage()->debugobj(new My::Profiler()); + __PACKAGE__->storage()->debug(1); + +A more complicated example might involve storing each execution of SQL in an +array: + + sub query_end { + my $self = shift(); + my $sql = shift(); + my @params = @_; + + my $elapsed = time() - $start; + push(@{ $calls{$sql} }, { + params => \@params, + elapsed => $elapsed + }); + } + +You could then create average, high and low execution times for an SQL +statement and dig down to see if certain parameters cause aberrant behavior. + +=head2 Getting the value of the primary key for the last database insert + +AKA getting last_insert_id + +If you are using PK::Auto, this is straightforward: + + my $foo = $rs->create(\%blah); + # do more stuff + my $id = $foo->id; # foo->my_primary_key_field will also work. + +If you are not using autoincrementing primary keys, this will probably +not work, but then you already know the value of the last primary key anyway. + =cut