+=head2 get_bugs_by_db
+
+This routine uses the database to try to speed up
+searches.
+
+
+=cut
+
+state $_get_bugs_by_db_options =
+ {hash_slice(%_get_bugs_common_options,
+ (qw(package submitter severity tag archive),
+ qw(owner src maint bugs correspondent),
+ qw(affects usertags))
+ ),
+ schema => {type => OBJECT,
+ },
+ };
+sub get_bugs_by_db{
+ my %param = validate_with(params => \@_,
+ spec => $_get_bugs_by_db_options,
+ );
+ my %bugs = ();
+
+ my $s = $param{schema};
+ my $keys = grep {$_ !~ $_non_search_key_regex} keys(%param);
+ die "Need at least 1 key to search by" unless $keys;
+ my $rs = $s->resultset('Bug');
+ if (exists $param{severity}) {
+ $rs = $rs->search({'severity.severity' =>
+ [make_list($param{severity})],
+ },
+ {join => 'severity'},
+ );
+ }
+ for my $key (qw(owner submitter done)) {
+ if (exists $param{$key}) {
+ $rs = $rs->search({"${key}.addr" =>
+ [make_list($param{$key})],
+ },
+ {join => $key},
+ );
+ }
+ }
+ if (exists $param{correspondent}) {
+ my $message_rs =
+ $s->resultset('Message')->
+ search({'correspondent.addr' =>
+ [make_list($param{correspondent})],
+ },
+ {join => {message_correspondents => 'correspondent'},
+ columns => ['id'],
+ group_by => ['me.id'],
+ },
+ );
+ $rs = $rs->search({'bug_messages.message' =>
+ {-in => $message_rs->get_column('id')->as_query()},
+ },
+ {join => 'bug_messages',
+ },
+ );
+ }
+ if (exists $param{affects}) {
+ my @aff_list = make_list($param{affects});
+ $rs = $rs->search({-or => {'bin_pkg.pkg' =>
+ [@aff_list],
+ 'src_pkg.pkg' =>
+ [@aff_list],
+ 'me.unknown_affects' =>
+ [@aff_list]
+ },
+ },
+ {join => [{bug_affects_binpackages => 'bin_pkg'},
+ {bug_affects_srcpackages => 'src_pkg'},
+ ],
+ },
+ );
+ }
+ if (exists $param{package}) {
+ $rs = $rs->search({-or => {'bin_pkg.pkg' =>
+ [make_list($param{package})],
+ 'me.unknown.package' =>
+ [make_list($param{package})]},
+ },
+ {join => {bug_binpackages => 'bin_pkg'}});
+ }
+ if (exists $param{maint}) {
+ my @maint_list =
+ map {$_ eq '' ? undef : $_}
+ make_list($param{maint});
+ my $bin_pkgs_rs =
+ $s->resultset('BinPkg')->
+ search({'correspondent.addr' => [@maint_list]},
+ {join => {bin_vers =>
+ {src_ver =>
+ {maintainer => 'correspondent'}}},
+ columns => ['id'],
+ group_by => ['me.id'],
+ },
+ );
+ my $src_pkgs_rs =
+ $s->resultset('SrcPkg')->
+ search({'correspondent.addr' => [@maint_list]},
+ {join => {src_vers =>
+ {maintainer => 'correspondent'}},
+ columns => ['id'],
+ group_by => ['me.id'],
+ },
+ );
+ $rs = $rs->search({-or => {'bug_binpackages.bin_pkg' =>
+ { -in => $bin_pkgs_rs->get_column('id')->as_query},
+ 'bug_srcpackages.src_pkg' =>
+ { -in => $bin_pkgs_rs->get_column('id')->as_query},
+ },
+ },
+ {join => ['bug_binpackages',
+ 'bug_srcpackages',
+ ]}
+ );
+ }
+ if (exists $param{src}) {
+ # identify all of the srcpackages and binpackages that match first
+ my $src_pkgs_rs =
+ $s->resultset('SrcPkg')->
+ search({-or => [map {('me.pkg' => $_,
+ )}
+ make_list($param{src})],
+ columns => ['id'],
+ group_by => ['me.id'],
+ },
+ );
+ my $bin_pkgs_rs =
+ $s->resultset('BinPkg')->
+ search({-or => [map {('src_pkg.pkg' => $_,
+ )}
+ make_list($param{src})],
+ },
+ {join => {bin_vers => {src_ver => 'src_pkg'}},
+ columns => ['id'],
+ group_by => ['me.id'],
+ });
+ $rs = $rs->search({-or => {'bug_binpackages.bin_pkg' =>
+ { -in => $bin_pkgs_rs->get_column('id')->as_query},
+ 'bug_srcpackages.src_pkg' =>
+ { -in => $bin_pkgs_rs->get_column('id')->as_query},
+ 'me.unknown_package' =>
+ [make_list($param{src})],
+ },
+ },
+ {join => ['bug_binpackages',
+ 'bug_srcpackages',
+ ]}
+ );
+ }
+ # tags are very odd, because we must handle usertags.
+ if (exists $param{tag}) {
+ # bugs from usertags which matter
+ my %bugs_matching_usertags;
+ for my $bug (make_list(grep {defined $_ }
+ @{$param{usertags}}{make_list($param{tag})})) {
+ $bugs_matching_usertags{$bug} = 1;
+ }
+ # we want all bugs which either match the tag name given in
+ # param, or have a usertag set which matches one of the tag
+ # names given in param.
+ $rs = $rs->search({-or => {map {('tag.tag' => $_)}
+ make_list($param{tag}),
+ map {('me.id' => $_)}
+ keys %bugs_matching_usertags
+ },
+ },
+ {join => {bug_tags => 'tag'}});
+ }
+ if (exists $param{bugs}) {
+ $rs = $rs->search({-or => {map {('me.id' => $_)}
+ make_list($param{bugs})}
+ });
+ }
+ # handle archive
+ if (defined $param{archive} and $param{archive} ne 'both') {
+ $rs = $rs->search({'me.archived' => $param{archive}});
+ }
+ return $rs->get_column('id')->all();
+}
+
+