]> git.donarmstrong.com Git - debbugs.git/blobdiff - Debbugs/Collection/Bug.pm
Merge branch 'mouseify'
[debbugs.git] / Debbugs / Collection / Bug.pm
diff --git a/Debbugs/Collection/Bug.pm b/Debbugs/Collection/Bug.pm
new file mode 100644 (file)
index 0000000..3f40b0c
--- /dev/null
@@ -0,0 +1,216 @@
+# This module is part of debbugs, and
+# is released under the terms of the GPL version 2, or any later
+# version (at your option). See the file README and COPYING for more
+# information.
+# Copyright 2018 by Don Armstrong <don@donarmstrong.com>.
+
+package Debbugs::Collection::Bug;
+
+=head1 NAME
+
+Debbugs::Collection::Bug -- Bug generation factory
+
+=head1 SYNOPSIS
+
+This collection extends L<Debbugs::Collection> and contains members of
+L<Debbugs::Bug>. Useful for any field which contains one or more bug or tracking
+lists of packages
+
+=head1 DESCRIPTION
+
+
+
+=head1 METHODS
+
+=cut
+
+use Mouse;
+use strictures 2;
+use namespace::autoclean;
+use Debbugs::Common qw(make_list hash_slice);
+use Debbugs::OOTypes;
+use Debbugs::Status qw(get_bug_statuses);
+use Debbugs::Collection::Package;
+use Debbugs::Collection::Correspondent;
+
+use Debbugs::Bug;
+
+extends 'Debbugs::Collection';
+
+=head2 my $bugs = Debbugs::Collection::Bug->new(%params|$param)
+
+Parameters in addition to those defined by L<Debbugs::Collection>
+
+=over
+
+=item package_collection
+
+Optional L<Debbugs::Collection::Package> which is used to look up packages
+
+
+=item correspondent_collection
+
+Optional L<Debbugs::Collection::Correspondent> which is used to look up correspondents
+
+
+=item users
+
+Optional arrayref of L<Debbugs::User> which set usertags for bugs in this collection
+
+=back
+
+=head2 $bugs->package_collection()
+
+Returns the package collection that this bug collection is using
+
+=head2 $bugs->correspondent_collection()
+
+Returns the correspondent collection that this bug collection is using
+
+=head2 $bugs->users()
+
+Returns the arrayref of users that this bug collection is using
+
+=head2 $bugs->add_user($user)
+
+Add a user to the set of users that this bug collection is using
+
+=head2 $bugs->load_related_packages_and_versions()
+
+Preload all of the related packages and versions for the bugs in this bug
+collection. You should call this if you plan on calculating whether the bugs in
+this collection are present/absent.
+
+=cut
+
+has '+members' => (isa => 'ArrayRef[Bug]');
+has 'package_collection' =>
+    (is => 'ro',
+     isa => 'Debbugs::Collection::Package',
+     builder => '_build_package_collection',
+     lazy => 1,
+    );
+
+sub _build_package_collection {
+    my $self = shift;
+    return Debbugs::Collection::Package->new($self->has_schema?(schema => $self->schema):());
+}
+
+has 'correspondent_collection' =>
+    (is => 'ro',
+     isa => 'Debbugs::Collection::Correspondent',
+     builder => '_build_correspondent_collection',
+     lazy => 1,
+    );
+
+sub _build_correspondent_collection {
+    my $self = shift;
+    return Debbugs::Collection::Correspondent->new($self->has_schema?(schema => $self->schema):());
+}
+
+has 'users' =>
+    (is => 'ro',
+     isa => 'ArrayRef[Debbugs::User]',
+     traits => ['Array'],
+     default => sub {[]},
+     handles => {'add_user' => 'push'},
+    );
+
+sub BUILD {
+    my $self = shift;
+    my $args = shift;
+    if (exists $args->{bugs}) {
+        $self->add(
+            $self->_member_constructor(bugs => $args->{bugs}
+                                      ));
+    }
+}
+
+sub _member_constructor {
+    # handle being called $self->_member_constructor;
+    my $self = shift;
+    my %args = @_;
+    my @return;
+    my $schema;
+    $schema = $self->schema if $self->has_schema;
+
+    if (defined $schema) {
+        my $statuses = get_bug_statuses(bug => [make_list($args{bugs})],
+                                        schema => $schema,
+                                       );
+        # preload as many of the packages as we need
+        my %packages;
+        while (my ($bug, $status) = each %{$statuses}) {
+            if (defined $status->{package}) {
+                $packages{$_} = 1 for split /,/, $status->{package};
+            }
+            if (defined $status->{source}) {
+                $packages{$_} = 1 for split /,/, $status->{source};
+            }
+        }
+        $self->package_collection->universe->add_by_key(keys %packages);
+        while (my ($bug, $status) = each %{$statuses}) {
+            push @return,
+                Debbugs::Bug->new(bug => $bug,
+                                  status =>
+                                  Debbugs::Bug::Status->new(status => $status,
+                                                            bug => $bug,
+                                                            status_source => 'db',
+                                                           ),
+                                  schema => $schema,
+                                  package_collection =>
+                                  $self->package_collection->universe,
+                                  bug_collection =>
+                                  $self->universe,
+                                  correspondent_collection =>
+                                  $self->correspondent_collection->universe,
+                                  @{$args{constructor_args}//[]},
+                                 );
+        }
+    } else {
+        for my $bug (make_list($args{bugs})) {
+            push @return,
+                Debbugs::Bug->new(bug => $bug,
+                                  package_collection =>
+                                  $self->package_collection->universe,
+                                  bug_collection =>
+                                  $self->universe,
+                                  correspondent_collection =>
+                                  $self->correspondent_collection->universe,
+                                  @{$args{constructor_args}//[]},
+                                 );
+        }
+    }
+    return @return;
+}
+
+around add_by_key => sub {
+    my $orig = shift;
+    my $self = shift;
+    my @members =
+        $self->_member_constructor(bugs => [@_],
+                                  );
+    return $self->$orig(@members);
+};
+
+sub member_key {
+    return $_[1]->bug;
+}
+
+sub load_related_packages_and_versions {
+    my $self = shift;
+    my @related_packages_and_versions =
+        $self->apply(sub {$_->related_packages_and_versions});
+    $self->package_collection->
+        add_packages_and_versions(@related_packages_and_versions);
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
+
+__END__
+# Local Variables:
+# indent-tabs-mode: nil
+# cperl-indent-level: 4
+# End: