forked from lix-project/hydra
Materialize the number of finished builds
The NrBuilds table tracks the value of ‘select count(*) from Builds where finished = 0’, keeping it up to date via a trigger. This is necessary to make the /all page fast, since otherwise it needs to do a sequential scan on the Builds table.
This commit is contained in:
parent
182f725612
commit
452c8e36d1
|
@ -56,13 +56,12 @@ sub all : Chained('get_builds') PathPart {
|
|||
|
||||
my $resultsPerPage = 20;
|
||||
|
||||
my $nrBuilds = $c->stash->{allBuilds}->search({finished => 1})->count;
|
||||
|
||||
$c->stash->{baseUri} = $c->uri_for($self->action_for("all"), $c->req->captures);
|
||||
|
||||
$c->stash->{page} = $page;
|
||||
$c->stash->{resultsPerPage} = $resultsPerPage;
|
||||
$c->stash->{total} = $nrBuilds;
|
||||
$c->stash->{total} = $c->stash->{allBuilds}->search({finished => 1})->count
|
||||
unless defined $c->stash->{total};
|
||||
|
||||
$c->stash->{builds} = [ $c->stash->{allBuilds}->search(
|
||||
{ finished => 1 },
|
||||
|
|
|
@ -155,6 +155,7 @@ sub get_builds : Chained('/') PathPart('') CaptureArgs(0) {
|
|||
$c->stash->{allJobs} = $c->model('DB::Jobs');
|
||||
$c->stash->{latestSucceeded} = $c->model('DB')->resultset('LatestSucceeded');
|
||||
$c->stash->{channelBaseName} = "everything";
|
||||
$c->stash->{total} = $c->model('DB::NrBuilds')->find('finished')->count;
|
||||
}
|
||||
|
||||
|
||||
|
|
75
src/lib/Hydra/Schema/NrBuilds.pm
Normal file
75
src/lib/Hydra/Schema/NrBuilds.pm
Normal file
|
@ -0,0 +1,75 @@
|
|||
use utf8;
|
||||
package Hydra::Schema::NrBuilds;
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader
|
||||
# DO NOT MODIFY THE FIRST PART OF THIS FILE
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Hydra::Schema::NrBuilds
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use base 'DBIx::Class::Core';
|
||||
|
||||
=head1 COMPONENTS LOADED
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L<Hydra::Component::ToJSON>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->load_components("+Hydra::Component::ToJSON");
|
||||
|
||||
=head1 TABLE: C<NrBuilds>
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->table("NrBuilds");
|
||||
|
||||
=head1 ACCESSORS
|
||||
|
||||
=head2 what
|
||||
|
||||
data_type: 'text'
|
||||
is_nullable: 0
|
||||
|
||||
=head2 count
|
||||
|
||||
data_type: 'integer'
|
||||
is_nullable: 0
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->add_columns(
|
||||
"what",
|
||||
{ data_type => "text", is_nullable => 0 },
|
||||
"count",
|
||||
{ data_type => "integer", is_nullable => 0 },
|
||||
);
|
||||
|
||||
=head1 PRIMARY KEY
|
||||
|
||||
=over 4
|
||||
|
||||
=item * L</what>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
__PACKAGE__->set_primary_key("what");
|
||||
|
||||
|
||||
# Created by DBIx::Class::Schema::Loader v0.07033 @ 2013-08-12 17:59:18
|
||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CK8eJGC803nGj0wnete9xg
|
||||
|
||||
|
||||
# You can replace this text with custom code or comments, and it will be preserved on regeneration
|
||||
1;
|
|
@ -51,12 +51,12 @@ for (my $n = $schemaVersion; $n < $maxSchemaVersion; $n++) {
|
|||
my @statements = $sql_splitter->split($schema);
|
||||
eval {
|
||||
$dbh->begin_work;
|
||||
sub run {
|
||||
sub run_ {
|
||||
my ($stm) = @_;
|
||||
print STDERR "executing SQL statement: $stm\n";
|
||||
$dbh->do($_);
|
||||
}
|
||||
run($_) foreach @statements;
|
||||
run_($_) foreach @statements;
|
||||
$db->resultset('SchemaVersion')->update({version => $m});
|
||||
$dbh->commit;
|
||||
};
|
||||
|
|
|
@ -514,6 +514,36 @@ create table NewsItems (
|
|||
);
|
||||
|
||||
|
||||
-- Cache of the number of finished builds.
|
||||
create table NrBuilds (
|
||||
what text primary key not null,
|
||||
count integer not null
|
||||
);
|
||||
|
||||
insert into NrBuilds(what, count) values('finished', 0);
|
||||
|
||||
#ifdef POSTGRESQL
|
||||
|
||||
create function modifyNrBuildsFinished() returns trigger as $$
|
||||
begin
|
||||
if ((tg_op = 'INSERT' and new.finished = 1) or
|
||||
(tg_op = 'UPDATE' and old.finished = 0 and new.finished = 1)) then
|
||||
update NrBuilds set count = count + 1 where what = 'finished';
|
||||
elsif ((tg_op = 'DELETE' and old.finished = 1) or
|
||||
(tg_op = 'UPDATE' and old.finished = 1 and new.finished = 0)) then
|
||||
update NrBuilds set count = count - 1 where what = 'finished';
|
||||
end if;
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger NrBuildsFinished after insert or update or delete on Builds
|
||||
for each row
|
||||
execute procedure modifyNrBuildsFinished();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
-- Some indices.
|
||||
|
||||
create index IndexBuildInputsOnBuild on BuildInputs(build);
|
||||
|
@ -534,7 +564,7 @@ create index IndexBuildsOnJobAndSystem on Builds(project, jobset, job, system);
|
|||
create index IndexBuildsOnJobset on Builds(project, jobset);
|
||||
create index IndexBuildsOnProject on Builds(project);
|
||||
create index IndexBuildsOnTimestamp on Builds(timestamp);
|
||||
create index IndexBuildsOnJobsetFinishedTimestamp on Builds(project, jobset, finished, timestamp DESC);
|
||||
create index IndexBuildsOnJobsetFinishedTimestamp on Builds(project, jobset, finished, timestamp DESC); -- obsolete?
|
||||
create index IndexBuildsOnJobFinishedId on builds(project, jobset, job, system, finished, id DESC);
|
||||
create index IndexBuildsOnJobSystemCurrent on Builds(project, jobset, job, system, isCurrent);
|
||||
create index IndexBuildsOnDrvPath on Builds(drvPath);
|
||||
|
|
23
src/sql/upgrade-17.sql
Normal file
23
src/sql/upgrade-17.sql
Normal file
|
@ -0,0 +1,23 @@
|
|||
create table NrBuilds (
|
||||
what text primary key not null,
|
||||
count integer not null
|
||||
);
|
||||
|
||||
create function modifyNrBuildsFinished() returns trigger as $$
|
||||
begin
|
||||
if ((tg_op = 'INSERT' and new.finished = 1) or
|
||||
(tg_op = 'UPDATE' and old.finished = 0 and new.finished = 1)) then
|
||||
update NrBuilds set count = count + 1 where what = 'finished';
|
||||
elsif ((tg_op = 'DELETE' and old.finished = 1) or
|
||||
(tg_op = 'UPDATE' and old.finished = 1 and new.finished = 0)) then
|
||||
update NrBuilds set count = count - 1 where what = 'finished';
|
||||
end if;
|
||||
return null;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create trigger NrBuildsFinished after insert or update or delete on Builds
|
||||
for each row
|
||||
execute procedure modifyNrBuildsFinished();
|
||||
|
||||
insert into NrBuilds(what, count) select 'finished', count(*) from Builds where finished = 1;
|
|
@ -7,11 +7,11 @@ my $db = Hydra::Model::DB->new;
|
|||
my @sources = $db->schema->sources;
|
||||
my $nrtables = scalar(@sources);
|
||||
|
||||
use Test::Simple tests => 43;
|
||||
use Test::Simple tests => 44;
|
||||
|
||||
foreach my $source (@sources) {
|
||||
my $title = "Basic select query for $source";
|
||||
if ($source eq "SchemaVersion") {
|
||||
if ($source eq "SchemaVersion" || $source eq "NrBuilds") {
|
||||
ok(scalar($db->resultset($source)->all) == 1, $title);
|
||||
} elsif( $source !~ m/^(LatestSucceeded|JobStatus|ActiveJobs)/) {
|
||||
ok(scalar($db->resultset($source)->all) == 0, $title);
|
||||
|
|
Loading…
Reference in a new issue