From: Guillermo Roditi Date: Tue, 16 Dec 2008 21:27:06 +0000 (+0000) Subject: Introduce 'any_null_means_no_value' option to eliminate wasteful queries. The option... X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c89815db08bb4cc35d69efefa8a27bf71ae13142;p=dbsrgits%2FDBIx-Class-Historic.git Introduce 'any_null_means_no_value' option to eliminate wasteful queries. The option is off by default and must be explicitly turned on. Tests, + docs included --- diff --git a/Changes b/Changes index 8bd0118..4a114eb 100644 --- a/Changes +++ b/Changes @@ -3,6 +3,9 @@ Revision history for DBIx::Class - Classes submitted as result_class for a resultsource are now automatically loaded via ensure_loaded() - 'result_class' resultset attribute, identical to result_class() + - add 'any_null_means_no_value' option for relationship accessors of + type 'single'. This will prevent DBIC from querying the database + if one or more of the key columns IS NULL. Tests + docs (groditi) 0.08099_05 2008-10-30 21:30:00 (UTC) - Rewritte of Storage::DBI::connect_info(), extended with an diff --git a/lib/DBIx/Class/Relationship.pm b/lib/DBIx/Class/Relationship.pm index b3f8507..ce8a96f 100644 --- a/lib/DBIx/Class/Relationship.pm +++ b/lib/DBIx/Class/Relationship.pm @@ -208,6 +208,13 @@ Cascading deletes are off by default on a C relationship. To turn them on, pass C<< cascade_delete => 1 >> in the $attr hashref. +By default, DBIC will attempt to query the related table for a row when the +relationship accessor is called even if a foreign key member column IS NULL, +which can be wasteful. To avoid this query from being performed, pass +C<< any_null_means_no_value => 1 >> in the C<$attr> hashref. This only applies +to accessors of type 'single' (when your accessor and foreign key have +different names e.g. 'cd_id', and 'cd'). + NOTE: If you are used to L relationships, this is the equivalent of C. diff --git a/lib/DBIx/Class/Relationship/Accessor.pm b/lib/DBIx/Class/Relationship/Accessor.pm index d9c24a4..f23ec4c 100644 --- a/lib/DBIx/Class/Relationship/Accessor.pm +++ b/lib/DBIx/Class/Relationship/Accessor.pm @@ -18,7 +18,7 @@ sub add_relationship_accessor { my ($class, $rel, $acc_type) = @_; my %meth; if ($acc_type eq 'single') { - my $rel_cond = $class->relationship_info($rel)->{cond}; + my $rel_info = $class->relationship_info($rel); $meth{$rel} = sub { my $self = shift; if (@_) { @@ -28,9 +28,12 @@ sub add_relationship_accessor { return $self->{_relationship_data}{$rel}; } else { my $cond = $self->result_source->resolve_condition( - $rel_cond, $rel, $self + $rel_info->{cond}, $rel, $self ); - return if grep { not defined } values %$cond; + if( exists $rel_info->{attrs}->{any_null_means_no_value} + && $rel_info->{attrs}->{any_null_means_no_value} ){ + return if grep { not defined } values %$cond; + } my $val = $self->find_related($rel, {}, {}); return unless $val; return $self->{_relationship_data}{$rel} = $val; diff --git a/t/66relationship.t b/t/66relationship.t index 3a96107..bfe7781 100644 --- a/t/66relationship.t +++ b/t/66relationship.t @@ -8,7 +8,7 @@ use DBICTest; my $schema = DBICTest->init_schema(); -plan tests => 72; +plan tests => 73; # has_a test my $cd = $schema->resultset("CD")->find(4); @@ -41,7 +41,18 @@ if ($INC{'DBICTest/HelperRels.pm'}) { } ); } -is( ($artist->search_related('cds'))[3]->title, 'Big Flop', 'create_related ok' ); +my $big_flop_cd = ($artist->search_related('cds'))[3]; +is( $big_flop_cd->title, 'Big Flop', 'create_related ok' ); + +{ # make sure we are not making pointless select queries when a FK IS NULL + my $queries = 0; + $schema->storage->debugcb(sub { $queries++; }); + $schema->storage->debug(1); + $big_flop_cd->genre; #should not trigger a select query + is($queries, 0, 'No Select made for belongs_to if key IS NULL'); + $schema->storage->debug(0); + $schema->storage->debugcb(undef); +} my( $rs_from_list ) = $artist->search_related_rs('cds'); is( ref($rs_from_list), 'DBIx::Class::ResultSet', 'search_related_rs in list context returns rs' ); diff --git a/t/lib/DBICTest/Schema/CD.pm b/t/lib/DBICTest/Schema/CD.pm index 6175be4..0c79e60 100644 --- a/t/lib/DBICTest/Schema/CD.pm +++ b/t/lib/DBICTest/Schema/CD.pm @@ -67,7 +67,7 @@ __PACKAGE__->belongs_to('genre', 'DBICTest::Schema::Genre', join_type => 'left', on_delete => 'SET NULL', on_update => 'CASCADE', - + any_null_means_no_value => 1, }, );