switched to using _with_meta_key and _with_meta_hash
Luke Saunders [Wed, 19 May 2010 15:50:35 +0000 (16:50 +0100)]
lib/DBIx/Class/ResultSet/WithMetaData.pm
t/custom_methods.t
t/lib/DBICTest/Schema/ResultSet/Artist.pm

index 5e5696e..15cc209 100644 (file)
@@ -23,7 +23,12 @@ has 'id_cols' => (
   isa => 'ArrayRef',
 );
 
-has '_modifiers' => (
+has '_hash_modifiers' => (
+  is => 'rw',
+  isa => 'ArrayRef',
+);
+
+has '_key_modifiers' => (
   is => 'rw',
   isa => 'ArrayRef',
 );
@@ -51,8 +56,7 @@ DBIx::Class::ResultSet::WithMetaData
   method with_substr () {
     $self->build_metadata( modifier => sub () {
       my $row = shift;
-      my $substr = substr($row->{name}, 0, 3);
-      $row->{substr} = $substr;
+      $row->{substr} = substr($row->{name}, 0, 3);
       return $row;
     });
     return $self;
@@ -95,7 +99,7 @@ sub new {
   my $self = shift;
 
   my $new = $self->next::method(@_);
-  foreach my $key (qw/_row_info was_row id_cols _modifiers/) {
+  foreach my $key (qw/_row_info was_row id_cols _key_modifiers _hash_modifiers/) {
     alias $new->{$key} = $new->{attrs}{$key};
   }
 
@@ -103,8 +107,11 @@ sub new {
     $new->_row_info({});
   }
 
-  unless ($new->_modifiers) {
-    $new->_modifiers([]);
+  unless ($new->_key_modifiers) {
+    $new->_key_modifiers([]);
+  }
+  unless ($new->_hash_modifiers) {
+    $new->_hash_modifiers([]);
   }
 
   unless ($new->id_cols && scalar(@{$new->id_cols})) {
@@ -142,12 +149,23 @@ method display () {
       $row = { %{$row}, %{$info} };
     }
 
-    foreach my $modifier (@{$rs->_modifiers}) {
-      my $new_row = $modifier->($row);
-      if (ref $new_row ne 'HASH') {
-        die 'modifier subref (added via build_metadata did not return hashref)';
+    foreach my $modifier (@{$rs->_hash_modifiers}) {
+      my $row_hash = $modifier->($row);
+      if (ref $row_hash ne 'HASH') {
+        die 'modifier subref (added via build_metadata) did not return hashref';
+      }
+
+      # simple merge for now, potentially needs to be more complex
+      $row->{$_} = $row_hash->{$_} for keys %{$row_hash};
+    }
+
+    foreach my $params (@{$rs->_key_modifiers}) {
+      my $modifier = $params->{modifier};
+      my $key = $params->{key};
+
+      if (my $val = $modifier->($row)) {
+        $row->{$key} = $val;
       }
-      $row = $new_row;
     }
     push(@rows, $row);
   }
@@ -155,35 +173,68 @@ method display () {
   return ($self->was_row) ? $rows[0] : \@rows;
 }
 
-=head2 build_metadata
+=head2 _with_meta_key
 
 =over 4
 
-=item Arguments: modifier => subref($row_hash)
+=item Arguments: key_name => subref($row_hash)
 
 =item Return Value: ResultSet
 
 =back
 
- $self->build_metadata( modifier => sub ($row) { 
-   $row->{dates} = [qw/mon weds fri/];
-   return $row;
+ $self->_with_meta_key( substr => sub ($row) { 
+   return substr(shift->{name}, 0, 3);
  });
 
-This method allows you to alter the hash to add additional metadata to it
-at L</display> time.
+This method allows you populate a certain key for each row hash at  L</display> time.
 
 =cut
 
-method build_metadata (%opts) {
-  my ($modifier) = map { $opts{$_} } qw/modifier/;
+method _with_meta_key ($key, $modifier) {
+  my $rs = $self->search({});
+  unless ($key) {
+    die 'build_metadata called without key';
+  }
+
   unless ($modifier && (ref $modifier eq 'CODE')) {
     die 'build_metadata called without modifier param';
   }
 
-  push( @{$self->_modifiers}, $modifier );
+  push( @{$rs->_key_modifiers}, { key => $key, modifier => $modifier });
+  return $rs;
 }
 
+=head2 _with_meta_hash
+
+=over 4
+
+=item Arguments: subref($row_hash)
+
+=item Return Value: ResultSet
+
+=back
+
+ $self->_with_meta_hash( sub ($row) { 
+   my $row = shift;
+   my $return_hash = { substr => substr($row->{name}, 0, 3), substr2 => substr($row->{name}, 0, 4) };
+   return $return_hash;
+ });
+
+Use this method when you want to populate multiple keys of the hash at the same time. If you just want to 
+populate one key, use L</_with_meta_key>.
+
+=cut
+
+method _with_meta_hash ($modifier) {
+  my $rs = $self->search({});
+  unless ($modifier && (ref $modifier eq 'CODE')) {
+    die 'build_metadata called without modifier param';
+  }
+
+  push( @{$rs->_hash_modifiers}, $modifier );
+  return $rs;
+}
 
 =head2 add_row_info (DEPRECATED)
 
index 9db7886..1fd689d 100644 (file)
@@ -27,7 +27,31 @@ ok(my $schema = DBICTest->init_schema(), 'got schema');
 }
 
 {
-       my $artists = $schema->resultset('Artist')->search({}, { order_by => 'artistid' })->with_substr->display();
+       my $artists = $schema->resultset('Artist')->search({}, { order_by => 'artistid' })->with_substr_multi->display();
+       is_deeply($artists, [
+               {
+                       'artistid' => '1',
+                       'name' => 'Caterwauler McCrae',
+                       'substr' => 'Cat',
+                       'substr2' => 'Cate'
+               },
+               {
+                       'artistid' => '2',
+                       'name' => 'Random Boy Band',
+                       'substr' => 'Ran',
+                       'substr2' => 'Rand'
+               },
+               {
+                       'artistid' => '3',
+                       'name' => 'We Are Goth',
+                       'substr' => 'We ',
+                       'substr2' => 'We A'
+               }
+       ], 'display with substring using _with_meta_hash okay');
+}
+
+{
+       my $artists = $schema->resultset('Artist')->search({}, { order_by => 'artistid' })->with_substr_key->display();
        is_deeply($artists, [
                {
                        'artistid' => '1',
@@ -44,7 +68,7 @@ ok(my $schema = DBICTest->init_schema(), 'got schema');
                        'name' => 'We Are Goth',
                        'substr' => 'We '
                }
-       ], 'display with substring okay');
+       ], 'display with substring using _with_meta_key okay');
 }
 
 # {
@@ -69,7 +93,7 @@ ok(my $schema = DBICTest->init_schema(), 'got schema');
 # }
 
 {
-       my $artists = $schema->resultset('Artist')->search({}, { order_by => 'artistid' })->with_substr->search({}, { prefetch => 'cds', rows => 1 })->display();
+       my $artists = $schema->resultset('Artist')->search({}, { order_by => 'artistid' })->with_substr_key->search({}, { prefetch => 'cds', rows => 1 })->display();
        is_deeply($artists, [
       { 
         'artistid' => 1,
index 94f4fe1..a3688f2 100644 (file)
@@ -4,18 +4,29 @@ use Moose;
 use Method::Signatures::Simple;
 extends 'DBICTest::Schema::ResultSet';
 
-method with_substr () {
-  $self->build_metadata( 
-    modifier => sub () {
+method with_substr_multi () {
+  $self->_with_meta_hash( 
+    sub {
       my $row = shift;
       my $substr = substr($row->{name}, 0, 3);
+      my $substr2 = substr($row->{name}, 0, 4);
       $row->{substr} = $substr;
+      $row->{substr2} = $substr2;
       return $row;
     }
   );
   return $self;
 }
 
+method with_substr_key () {
+  $self->_with_meta_key( 
+    substr => sub {
+      return substr(shift->{name}, 0, 3);
+    }
+  );
+  return $self;
+}
+
 method with_substr_old () {
   foreach my $row ($self->all) {
     my $substr = substr($row->name, 0, 3);