]> git.donarmstrong.com Git - debbugs.git/blobdiff - Debbugs/Bug/Status.pm
Debbugs:;Verison: add count and join methods; only use lazy building
[debbugs.git] / Debbugs / Bug / Status.pm
index 46c82dcf9af054011b0dc6ee2c4bb362a994d5d3..9209485690059479238bfde03e525917f82d2193 100644 (file)
@@ -53,9 +53,25 @@ has status_source => (is => 'ro',
                      writer => '_set_status_source',
                     );
 
+has _status => (is => 'bare',
+                writer => '_set_status',
+                reader => '_status',
+                predicate => '_has__status',
+               );
+
+my %field_methods;
+
 sub BUILD {
     my $self = shift;
     my $args = shift;
+    state $field_mapping =
+       {originator => 'submitter',
+        keywords => 'tags',
+        msgid => 'message_id',
+        blockedby => 'blocked_by',
+        found_versions => 'found',
+        fixed_versions => 'fixed',
+       };
     if (not exists $args->{status} and exists $args->{bug}) {
        if ($self->has_schema) {
            ($args->{status}) =
@@ -63,12 +79,6 @@ sub BUILD {
                search_rs({id => [make_list($args->{bug})]},
                         {result_class => 'DBIx::Class::ResultClass::HashRefInflator'})->
                             all();
-           state $field_mapping =
-              {originator => 'submitter',
-               blockedby => 'blocked_by',
-               found_versions => 'found',
-               fixed_versions => 'fixed',
-              };
            for my $field (keys %{$field_mapping}) {
                $args->{status}{$field_mapping->{$field}} =
                    $args->{status}{$field} if defined $args->{status}{$field};
@@ -77,55 +87,24 @@ sub BUILD {
            $self->_set_status_source('db');
        } else {
            $args->{status} = get_bug_status(bug=>$args->{bug});
-           state $field_mapping =
-              {originator => 'submitter',
-               keywords => 'tags',
-               msgid => 'message_id',
-               blockedby => 'blocked_by',
-               found_versions => 'found',
-               fixed_versions => 'fixed',
-              };
            for my $field (keys %{$field_mapping}) {
                $args->{status}{$field_mapping->{$field}} =
-                   $args->{status}{$field};
+                   $args->{status}{$field} if defined $args->{status}{$field};
            }
            $self->_set_status_source('filesystem');
        }
     } elsif (exists $args->{status}) {
+        for my $field (keys %{$field_mapping}) {
+            $args->{status}{$field_mapping->{$field}} =
+                $args->{status}{$field} if defined $args->{status}{$field};
+        }
        $self->_set_status_source('hashref');
     }
     if (exists $args->{status}) {
        if (ref($args->{status}) ne 'HASH') {
            croak "status must be a HASHREF (argument to __PACKAGE__)";
        }
-       # single value fields
-       for my $field (qw(submitter date subject message_id done severity unarchived),
-                      qw(owner summary outlook bug log_modified),
-                      qw(last_modified archived forwarded)) {
-           next unless defined $args->{status}{$field};
-           # we're going to let status override passed values in args for now;
-           # maybe this should change
-           my $field_method = $meta->find_method_by_name('_set_'.$field);
-           if (not defined $field_method) {
-               croak "Unable to find field method for _set_$field";
-           }
-           $field_method->($self,$args->{status}{$field});
-       }
-       # multi value fields
-       for my $field (qw(affects package tags blocks blocked_by mergedwith),
-                      qw(found fixed)) {
-           next unless defined $args->{status}{$field};
-           my $field_method = $meta->find_method_by_name('_set_'.$field);
-           my $split_field = $args->{status}{$field};
-           if (!ref($split_field)) {
-               $split_field =
-                   _build_split_field($args->{status}{$field},
-                                      $field);
-           }
-           $field_method->($self,
-                           $split_field,
-                           );
-       }
+        $self->_set_status($args->{status});
        delete $args->{status};
     }
 }
@@ -135,6 +114,15 @@ has saved => (is => 'ro', isa => 'Bool',
              writer => '_set_set_saved',
             );
 
+sub __field_or_def {
+    my ($self,$field,$default) = @_;
+    if ($self->_has__status) {
+        my $s = $self->_status()->{$field};
+        return $s if defined $s;
+    }
+    return $default;
+}
+
 =head2 Status Fields
 
 =cut
@@ -150,7 +138,13 @@ has saved => (is => 'ro', isa => 'Bool',
 has submitter =>
     (is => 'ro',
      isa => 'Str',
-     default => $config{maintainer_email},
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('submitter',
+                               $config{maintainer_email});
+      },
+     lazy => 1,
      writer => '_set_submitter',
     );
 
@@ -161,7 +155,12 @@ has submitter =>
 has date =>
     (is => 'ro',
      isa => 'Str',
-     builder => sub {return time},
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('date',
+                               time);
+      },
      lazy => 1,
      writer => '_set_date',
     );
@@ -173,7 +172,12 @@ has date =>
 has last_modified =>
     (is => 'ro',
      isa => 'Str',
-     builder => sub {return time},
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('last_modified',
+                               time);
+      },
      lazy => 1,
      writer => '_set_last_modified',
     );
@@ -185,7 +189,12 @@ has last_modified =>
 has log_modified =>
     (is => 'ro',
      isa => 'Str',
-     builder => sub {return time},
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('log_modified',
+                                time);
+      },
      lazy => 1,
      writer => '_set_log_modified',
     );
@@ -198,7 +207,13 @@ has log_modified =>
 has subject =>
     (is => 'ro',
      isa => 'Str',
-     default => 'No subject',
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('subject',
+                               'No subject');
+     },
+     lazy => 1,
      writer => '_set_subject',
     );
 
@@ -213,8 +228,11 @@ has message_id =>
      builder =>
      sub {
         my $self = shift;
-        return 'nomessageid.'.$self->date.'_'.
-            md5_hex($self->subject.$self->submitter).'@'.$config{email_domain},
+         $self->__field_or_def('message_id',
+                               'nomessageid.'.$self->date.'_'.
+                               md5_hex($self->subject.$self->submitter).
+                               '@'.$config{email_domain},
+                              );
      },
      writer => '_set_message_id',
     );
@@ -229,7 +247,13 @@ has message_id =>
 has severity =>
     (is => 'ro',
      isa => 'Str',
-     default => $config{default_severity},
+     lazy => 1,
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('severity',
+                               $config{default_severity});
+     },
      writer => '_set_severity',
     );
 
@@ -243,7 +267,13 @@ unarchived.
 has unarchived =>
     (is => 'ro',
      isa => 'Int',
-     default => 0,
+     lazy => 1,
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('unarchived',
+                               0);
+     },
      writer => '_set_unarchived',
     );
 
@@ -256,7 +286,13 @@ True if the bug is archived, false otherwise.
 has archived =>
     (is => 'ro',
      isa => 'Int',
-     default => 0,
+     lazy => 1,
+     builder =>
+     sub {
+         my $self = shift;
+         $self->__field_or_def('archived',
+                               0);
+     },
      writer => '_set_archived',
     );
 
@@ -276,8 +312,14 @@ for my $field (qw(owner unarchived summary outlook done forwarded)) {
     has $field =>
        (is => 'ro',
         isa => 'Str',
-        default => '',
+         builder =>
+         sub {
+             my $self = shift;
+             $self->__field_or_def($field,
+                                   '');
+         },
         writer => '_set_'.$field,
+         lazy => 1,
        );
     my $field_method = $meta->find_method_by_name($field);
     die "No field method for $field" unless defined $field_method;
@@ -306,9 +348,23 @@ for my $field (qw(affects package tags)) {
        (is => 'ro',
         traits => [qw(Array)],
         isa => 'ArrayRef[Str]',
-        default => sub {return []},
+         builder =>
+         sub {
+             my $self = shift;
+             if ($self->_has__status) {
+                 my $s = $self->_status()->{$field};
+                 if (!ref($s)) {
+                     $s = _build_split_field($s,
+                                             $field);
+                 }
+                 return $s;
+             }
+             return [];
+         },
         writer => '_set_'.$field,
         handles => {$field => 'elements',
+                     $field.'_count' => 'count',
+                     $field.'_join' => 'join',
                    },
         lazy => 1,
        );
@@ -327,14 +383,45 @@ for my $field (qw(affects package tags)) {
 
 =cut
 
+sub __hashref_field {
+    my ($self,$field) = @_;
+
+    if ($self->_has__status) {
+        my $s = $self->_status()->{$field};
+        if (!ref($s)) {
+            $s = _build_split_field($s,
+                                    $field);
+        }
+        return $s;
+    }
+    return [];
+}
+
 for my $field (qw(found fixed)) {
     has '_'.$field =>
        (is => 'ro',
         traits => ['Hash'],
         isa => 'HashRef[Str]',
+         builder =>
+         sub {
+             my $self = shift;
+             if ($self->_has__status) {
+                 my $s = $self->_status()->{$field};
+                 if (!ref($s)) {
+                     $s = _build_split_field($s,
+                                             $field);
+                 }
+                 if (ref($s) ne 'HASH') {
+                     $s = {map {$_,'1'} @{$s}};
+                 }
+                 return $s;
+             }
+             return {};
+         },
         default => sub {return {}},
         writer => '_set_'.$field,
         handles => {$field => 'keys',
+                     $field.'_count' => 'count',
                    },
         lazy => 1,
        );
@@ -344,6 +431,10 @@ for my $field (qw(found fixed)) {
                          sub {my $self = shift;
                               return [$field_method->($self)]
                           });
+       $meta->add_method($field.'_join'=>
+                         sub {my ($self,$joiner) = @_;
+                              return join($joiner,$field_method->($self));
+                          });
     }
 }
 
@@ -378,7 +469,24 @@ for my $field (qw(blocks blocked_by mergedwith)) {
        (is => 'ro',
         traits => ['Hash'],
         isa => 'HashRef[Int]',
-        default => sub {return {}},
+         builder =>
+         sub {
+             my $self = shift;
+             if ($self->_has__status) {
+                 my $s = $self->_status()->{$field};
+                 if (!ref($s)) {
+                     $s = _build_split_field($s,
+                                             $field);
+                 }
+                 if (ref($s) ne 'HASH') {
+                     $s = {map {$_,'1'} @{$s}};
+                 }
+                 return $s;
+             }
+             return {};
+         },
+        handles => {$field.'_count' => 'count',
+                   },
         writer => '_set_'.$field,
         lazy => 1,
        );
@@ -395,6 +503,10 @@ for my $field (qw(blocks blocked_by mergedwith)) {
                      sub {my $self = shift;
                           return [$field_method->($self)]
                       });
+    $meta->add_method($field.'_join'=>
+                      sub {my ($self,$joiner) = @_;
+                           return join($joiner,$field_method->($self));
+                       });
 }
 
 for (qw(blocks blocked_by mergedwith)) {