=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 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 => 'rw',
- isa => 'Debbugs::Collection::Package',
- default => sub {Debbugs::Collection::Package->new()}
- );
+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):());
+}
-around BUILDARGS => sub {
- my $orig = shift;
- my $class = shift;
+has 'correspondent_collection' =>
+ (is => 'ro',
+ isa => 'Debbugs::Collection::Correspondent',
+ builder => '_build_correspondent_collection',
+ lazy => 1,
+ );
- my %args;
- if (@_==1 and ref($_[0]) eq 'HASH') {
- %args = %{$_[0]};
- } else {
- %args = @_;
- }
- $args{members} //= [];
- if (exists $args{bugs}) {
- push @{$args{members}},
- _member_constructor(bugs => $args{bugs},
- hash_slice(%args,qw(schema constructor_args)),
- );
- delete $args{bugs};
+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}
+ ));
}
- return $class->$orig(%args);
-};
+}
sub _member_constructor {
# handle being called $self->_member_constructor;
- if ((@_ % 2) == 1) {
- shift;
- }
+ my $self = shift;
my %args = @_;
my @return;
- if (exists $args{schema}) {
+ my $schema;
+ $schema = $self->schema if $self->has_schema;
+
+ if (defined $schema) {
my $statuses = get_bug_statuses(bug => [make_list($args{bugs})],
- schema => $args{schema},
+ 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=>$status,
- schema=>$args{schema},
+ 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}//[]},
);
}
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}//[]},
);
}
my $orig = shift;
my $self = shift;
my @members =
- _member_constructor(bugs => [@_],
- $self->has_schema?(schema => $self->schema):(),
- constructor_args => $self->constructor_args,
- );
+ $self->_member_constructor(bugs => [@_],
+ );
return $self->$orig(@members);
};
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;