only add rels once when seen repeatedly
Matt S Trout [Sun, 24 Nov 2013 02:49:15 +0000 (02:49 +0000)]
lib/DBIx/Class/ResultSet/Role/DQMethods.pm
t/dq/remap.t
t/lib/DBICTest/Schema/CD.pm

index b186910..ed4eb4c 100644 (file)
@@ -53,16 +53,25 @@ sub _remap_identifiers {
     my $last = pop @el;
     my $p = $map;
     $p = $p->{$_} ||= {} for @el;
-    if (my $alias = $p->{''}{'-alias'}) {
-      return Identifier($alias, $last);
+    unless ($p->{''}) {
+      my $need = my $j = {};
+      $j = $j->{$_} = {} for @el;
+      my $rsrc = $map->{''}{-rsrc};
+      $rsrc = $rsrc->related_source($_) for @el;
+      push @need_join, $need;
+      my $alias = $storage->relname_to_table_alias(
+        $el[-1], ++$seen_join->{$el[-1]}
+      );
+      $p->{''} = { -alias => $alias, -rsrc => $rsrc };
     }
-    my $need = my $j = {};
-    $j = $j->{$_} = {} for @el;
-    push @need_join, $need;
-    my $alias = $storage->relname_to_table_alias(
-      $el[-1], ++$seen_join->{$el[-1]}
-    );
-    return Identifier($alias, $last);
+    my $info = $p->{''};
+    my $col_map = $info->{-column_mapping} ||= do {
+      my $colinfo = $info->{-rsrc}->columns_info;
+      +{ map +(($colinfo->{$_}{rename_for_dq}||$_) => $_), keys %$colinfo }
+    };
+    die "Invalid name on ".(join(',',@el)||'me').": $last"
+      unless $col_map->{$last};
+    return Identifier($info->{-alias}, $col_map->{$last});
   } $dq;
   return ($mapped, \@need_join);
 }
index e8beb52..cc90954 100644 (file)
@@ -17,9 +17,13 @@ $schema->source($_)->resultset_class('DBIx::Class::ResultSet::WithDQMethods')
 
 my $cds = $schema->resultset('CD');
 
+throws_ok {
+  $cds->_remap_identifiers(Identifier('name'))
+} qr/Invalid name on me: name/;
+
 is_deeply(
-  [ $cds->_remap_identifiers(Identifier('name')) ],
-  [ Identifier('me', 'name'), [] ],
+  [ $cds->_remap_identifiers(Identifier('title')) ],
+  [ Identifier('me', 'title'), [] ],
   'Remap column on me'
 );
 
@@ -36,4 +40,18 @@ is_deeply(
   'Remap column on rel with re-alias'
 );
 
+is_deeply(
+  [ $cds->_remap_identifiers(Identifier('artist_id')) ],
+  [ Identifier('me', 'artist'), [] ],
+  'Remap column w/column name rename'
+);
+
+my $double_name = expr { $_->artist->name == $_->artist->name }->{expr};
+
+is_deeply(
+  [ $cds->_remap_identifiers($double_name) ],
+  [ $double_name, [ { artist => {} } ] ],
+  'Remap column on rel only adds rel once'
+);
+
 done_testing;
index 45fdf6f..9429bdc 100644 (file)
@@ -17,6 +17,7 @@ __PACKAGE__->add_columns(
   },
   'artist' => {
     data_type => 'integer',
+    rename_for_dq => 'artist_id',
   },
   'title' => {
     data_type => 'varchar',