]> git.donarmstrong.com Git - debbugs.git/blob - Debbugs/Collection/Bug.pm
Document bug collection a bit more
[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 in addition to those defined by L<Debbugs::Collection>
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             if (defined $status->{package}) {
145                 $packages{$_} = 1 for split /,/, $status->{package};
146             }
147             if (defined $status->{source}) {
148                 $packages{$_} = 1 for split /,/, $status->{source};
149             }
150         }
151         $self->package_collection->universe->add_by_key(keys %packages);
152         while (my ($bug, $status) = each %{$statuses}) {
153             push @return,
154                 Debbugs::Bug->new(bug => $bug,
155                                   status =>
156                                   Debbugs::Bug::Status->new(status => $status,
157                                                             bug => $bug,
158                                                             status_source => 'db',
159                                                            ),
160                                   schema => $schema,
161                                   package_collection =>
162                                   $self->package_collection->universe,
163                                   bug_collection =>
164                                   $self->universe,
165                                   correspondent_collection =>
166                                   $self->correspondent_collection->universe,
167                                   @{$args{constructor_args}//[]},
168                                  );
169         }
170     } else {
171         for my $bug (make_list($args{bugs})) {
172             push @return,
173                 Debbugs::Bug->new(bug => $bug,
174                                   package_collection =>
175                                   $self->package_collection->universe,
176                                   bug_collection =>
177                                   $self->universe,
178                                   correspondent_collection =>
179                                   $self->correspondent_collection->universe,
180                                   @{$args{constructor_args}//[]},
181                                  );
182         }
183     }
184     return @return;
185 }
186
187 around add_by_key => sub {
188     my $orig = shift;
189     my $self = shift;
190     my @members =
191         $self->_member_constructor(bugs => [@_],
192                                   );
193     return $self->$orig(@members);
194 };
195
196 sub member_key {
197     return $_[1]->bug;
198 }
199
200 sub load_related_packages_and_versions {
201     my $self = shift;
202     my @related_packages_and_versions =
203         $self->apply(sub {$_->related_packages_and_versions});
204     $self->package_collection->
205         add_packages_and_versions(@related_packages_and_versions);
206 }
207
208 __PACKAGE__->meta->make_immutable;
209
210 1;
211
212 __END__
213 # Local Variables:
214 # indent-tabs-mode: nil
215 # cperl-indent-level: 4
216 # End: