]> git.donarmstrong.com Git - debbugs.git/blob - Debbugs/Collection/Bug.pm
Document Debbugs::Collection::Bug
[debbugs.git] / Debbugs / Collection / Bug.pm
1 # This module is part of debbugs, and
2 # is released under the terms of the GPL version 2, or any later
3 # version (at your option). See the file README and COPYING for more
4 # information.
5 # Copyright 2018 by Don Armstrong <don@donarmstrong.com>.
6
7 package Debbugs::Collection::Bug;
8
9 =head1 NAME
10
11 Debbugs::Collection::Bug -- Bug generation factory
12
13 =head1 SYNOPSIS
14
15 This collection extends L<Debbugs::Collection> and contains members of
16 L<Debbugs::Bug>. Useful for any field which contains one or more bug or tracking
17 lists of packages
18
19 =head1 DESCRIPTION
20
21
22
23 =head1 METHODS
24
25 =cut
26
27 use Mouse;
28 use strictures 2;
29 use namespace::autoclean;
30 use Debbugs::Common qw(make_list hash_slice);
31 use Debbugs::OOTypes;
32 use Debbugs::Status qw(get_bug_statuses);
33 use Debbugs::Collection::Package;
34 use Debbugs::Collection::Correspondent;
35
36 use Debbugs::Bug;
37
38 extends 'Debbugs::Collection';
39
40 =head2 my $bugs = Debbugs::Collection::Bug->new(%params|$param)
41
42 Parameters:
43
44 =over
45
46 =item package_collection
47
48 Optional L<Debbugs::Collection::Package> which is used to look up packages
49
50
51 =item correspondent_collection
52
53 Optional L<Debbugs::Collection::Correspondent> which is used to look up correspondents
54
55
56 =item users
57
58 Optional arrayref of L<Debbugs::User> which set usertags for bugs in this collection
59
60 =back
61
62 =head2 $bugs->package_collection()
63
64 Returns the package collection that this bug collection is using
65
66 =head2 $bugs->correspondent_collection()
67
68 Returns the correspondent collection that this bug collection is using
69
70 =head2 $bugs->users()
71
72 Returns the arrayref of users that this bug collection is using
73
74 =head2 $bugs->add_user($user)
75
76 Add a user to the set of users that this bug collection is using
77
78 =head2 $bugs->load_related_packages_and_versions()
79
80 Preload all of the related packages and versions for the bugs in this bug
81 collection. You should call this if you plan on calculating whether the bugs in
82 this collection are present/absent.
83
84 =cut
85
86 has '+members' => (isa => 'ArrayRef[Bug]');
87 has 'package_collection' =>
88     (is => 'ro',
89      isa => 'Debbugs::Collection::Package',
90      builder => '_build_package_collection',
91      lazy => 1,
92     );
93
94 sub _build_package_collection {
95     my $self = shift;
96     return Debbugs::Collection::Package->new($self->has_schema?(schema => $self->schema):());
97 }
98
99 has 'correspondent_collection' =>
100     (is => 'ro',
101      isa => 'Debbugs::Collection::Correspondent',
102      builder => '_build_correspondent_collection',
103      lazy => 1,
104     );
105
106 sub _build_correspondent_collection {
107     my $self = shift;
108     return Debbugs::Collection::Correspondent->new($self->has_schema?(schema => $self->schema):());
109 }
110
111 has 'users' =>
112     (is => 'ro',
113      isa => 'ArrayRef[Debbugs::User]',
114      traits => ['Array'],
115      default => sub {[]},
116      handles => {'add_user' => 'push'},
117     );
118
119 sub BUILD {
120     my $self = shift;
121     my $args = shift;
122     if (exists $args->{bugs}) {
123         $self->add(
124             $self->_member_constructor(bugs => $args->{bugs}
125                                       ));
126     }
127 }
128
129 sub _member_constructor {
130     # handle being called $self->_member_constructor;
131     my $self = shift;
132     my %args = @_;
133     my @return;
134     my $schema;
135     $schema = $self->schema if $self->has_schema;
136
137     if (defined $schema) {
138         my $statuses = get_bug_statuses(bug => [make_list($args{bugs})],
139                                         schema => $schema,
140                                        );
141         # preload as many of the packages as we need
142         my %packages;
143         while (my ($bug, $status) = each %{$statuses}) {
144             $packages{$_} = 1 for split /,/, $status->{package};
145             $packages{$_} = 1 for split /,/, $status->{source};
146         }
147         $self->package_collection->universe->add_by_key(keys %packages);
148         while (my ($bug, $status) = each %{$statuses}) {
149             push @return,
150                 Debbugs::Bug->new(bug => $bug,
151                                   status =>
152                                   Debbugs::Bug::Status->new(status => $status,
153                                                             bug => $bug,
154                                                             status_source => 'db',
155                                                            ),
156                                   schema => $schema,
157                                   package_collection =>
158                                   $self->package_collection->universe,
159                                   bug_collection =>
160                                   $self->universe,
161                                   correspondent_collection =>
162                                   $self->correspondent_collection->universe,
163                                   @{$args{constructor_args}//[]},
164                                  );
165         }
166     } else {
167         for my $bug (make_list($args{bugs})) {
168             push @return,
169                 Debbugs::Bug->new(bug => $bug,
170                                   package_collection =>
171                                   $self->package_collection->universe,
172                                   bug_collection =>
173                                   $self->universe,
174                                   correspondent_collection =>
175                                   $self->correspondent_collection->universe,
176                                   @{$args{constructor_args}//[]},
177                                  );
178         }
179     }
180     return @return;
181 }
182
183 around add_by_key => sub {
184     my $orig = shift;
185     my $self = shift;
186     my @members =
187         $self->_member_constructor(bugs => [@_],
188                                   );
189     return $self->$orig(@members);
190 };
191
192 sub member_key {
193     return $_[1]->bug;
194 }
195
196 sub load_related_packages_and_versions {
197     my $self = shift;
198     my @related_packages_and_versions =
199         $self->map(sub {$_->related_packages_and_versions});
200     $self->package_collection->
201         add_packages_and_versions(@related_packages_and_versions);
202 }
203
204 __PACKAGE__->meta->make_immutable;
205
206 1;
207
208 __END__
209 # Local Variables:
210 # indent-tabs-mode: nil
211 # cperl-indent-level: 4
212 # End: