They're replaced by aggregates, which are declarative, faster, and have a better interface.
YU6CND7C726EDVGK53HYDLVJNKP2WJHC6X2N2ZSEXPUSBO2GZIJAC H3J4HW33BIQYK4EP3E2XLF2IFRU6MQ5HQBTFPXPH5OMWGC346GSQC J4B6EM5RLEQ4CRSNGSPUJSYOBCI623UX7BYK64HPJO3G3LNU2W5QC POZRGZOU5A7ROG2H6SRTP4QU52ARQYNJLG3QKTZ476S2SKY323RQC 4LBNSOFKMQMTTC7OG72ICKIFIHFEDYQQKRGGT5O6EFRHLQPAV7ZQC TV6DJXBPQ255WUQY6QFW3VBM6ZO3EJ2CNOGKRIU5QZJRX6DG6WGQC VG4QG336SCZNWAXJERI3N5FO6PUAYFJV24CLI27ADUFPO74RVJKQC CJKPW2G7DEBOYIOREXXMTYR2BPB3WM35ZYEORH6UNE2KR4XAJLXAC GS4SFHCPF76AX2U4NLLJGUISF6Y4AHYWEW3GLTDCKVDDXLSIGXUQC AWMM5OGV5EM4ZA3T3SCCU6LMKVJHKI2JANCNA236MD3O7AELE5XAC BXHG3HYLCKXL35S2MCIBTXTP6UO55NASYE7XCLQP4PXPSVDMUIAQC D5QIOJGPKQJIYBUCSC3MFJ3TXLPNZ2XMI37GXMFRVRFWWR2VMTFAC P5X4P6VKS5CJOOLJRVL66GRJLDLVC3EKAVAHP2RJOXQJ7WTYAUBQC 3PNG7NIBQQURUUPRVQXYL342OT7JUUYOMY2JJNP6YDX7SYJDZMYAC 2BUX775ILK47LEDXNPSVUAKVLEKG54ODCXRG3474DHY5PHJJBNBQC 2YXO5ZGQU6YB7M3JTJA6VAGK3L25R7CJ6HBF2EV4VYKA4JORHYDQC KPZNJ33UUF6TK5OPB6K5KLM3ZEK7YV3IF32HTLJFURCO6ICDMGYAC XBU2ODSPGKXUPOV5CFKOBOJLCIU5BMMZ5YVWFR7CP2G5QQZ5GAJAC JARRBLZDQ2JZWY7IUVPTOT7WJMBPMLFLF2MGLVGOYROAAISYGLSAC AS2OXLRMJGRI64FIEM4T7EV24NZYIMPPR2EQN3SR5A2JBHVXNYXAC ZCTGG25SELGUTOYLG72N2I2OF7YQ6B7CIBPCP5ANMDDD4FIQ3YPQC HPEG2RHVNHOPB5T4ZRXANIRBMVOVY3B5GFETJRYOTDJFVAYH2TQAC OW6XV2YSTYTBR5JO4FKCYAH44WX5UI2HUPIM6UIEQF7SPV7RLQFQC KU33KNG3I2NHT6HFDAXQAHJHOSC6VGJ2C3K6ADTIREKZQEOVVORQC 3Y7AFJSSMMEXQEHA6O4UXYXY3YPP7G55ZG72U2WXFMZKOZDEKGKAC LZVO64YG43JD7YMZSCTZNOBS5ROZA4FMPKJW2YOMHX2V5PTGBVWQC ODNCGFQ5FPKFI624BVMLW7PJ2EFJOR3TY66OCZM42UNNTWBCF2TQC FPK5LF53CFUEKFYJ3IYXT4UTVC6IITWJOCFATMC4PLHEUP5SIEAAC AKAZKCR6GFCZQBR2ZJSZEI3SXW4S25V7X7JGHUYNUITQQSAVAF5AC UWVMQIAC2HQNSG2JQOPZGUOCQ5V2JFP2F7RCTF3WJLK7NHSD5PAAC SU566LI3TBPIEOOXKN3HWVUMGXCCHV3AX7QTYHCAMA5QGYAKUBAQC KXGOUX7PH4BOXPJRYRGDS4RY7RTXYWUXCRAB5JR3BLVS62PVKOQAC RBNQKATLSAKTGW2IRNB5CRV3SEH5F6E4BPVWX4BII7MH5TCIPINQC FHF6IZJQPUQHY5QWQYRPZVDBRLHREWRHGNKVQDT7F3GQKKLZXJKQC PKPWUHUXLGPQFQUTNHLVGWNT6AB3H2VMDCBKT6IPZDC53CEL4W7QC ECBA3GQOGTF73Y7A5EFUXZ5PDIZ5NPJM3WMOUJTE3AEK2PZQX3MQC SB2V735VJ2CDHGCXRUA5FOYHDRXQFVOZ3KXC3YKXWRNW6DIX7RXQC 3HCBU2FAXZMSF4JJR5Q64BSN66MBOGVETNHK33V2WSNDGOF4HHQAC JM3DPYOMVNMCL5GMEYC3Y4NDRGTNIFBBFTPGPVT66GPENVPU7EVQC AHTEIK7GGPHUC3AXIJ2NX4TI3RLX65XYKGAIIC6MC2S6I6QPWTAAC 3E6IP3R3JGH76PNGG7RCADV65KOV24HQXPXNLVVYIQ46AVYJRG3AC Y6AHH4THYQA43V77L43YM42DYRPCMDSWLUV4NKWAQYMPL4NTUIPQC LCKWLQW3TCEGY4E7FRZYWYSP7SHRA5LNJ2A7TWU4LVIRZTF7K7ZQC V4RNHJNR3WIBINRVD5MADTLUQWMCOMWHBD43MDV2XD7S6BRLL2YAC VJHIHMEHNE27HYL4CLC5J3SNALGPRSHYKQO2A65P5ORMTJEI42WQC 37R34XJOGMP3E3DD4RGGRX5LBW2LGB6J3E6XOXLWSU2QEIWBEM4QC D3DIBMOKXK2E65267BEEWQL4S4NSHGZBCY7YTU34JSEPZ7AKNBRQC 4D4U5IPYZO2FONPOET4UP3ZPVPB35Q47SXU7A56G76V7VDFILOIAC GNIEG2GCT6BUYHY2WXUAQVKHSYB6TVQT52O5GEY6COLKFK4ODCCQC BHZXGT2HWAMFNVBUDG7VR5HNA2SUJBUSMWB7EHTECB4QJ5HVYANAC EYNG4EL4N7LDQD4XKVVLYCDBCRHJZIEEYU7KQWDTAVADVE34TVZQC S6OISBQ3HPFHAAQ5ENG7N3MNGOPNEJPIFKSSA5N4G6KJQTQBSSLQC KN3VYE5P2RJB3KZ355LA5C2T2D5S2IR3QZFE53AJIWUVMETEEYDAC S5PV6IIMKJ7PGWIFLLXERHYF3BCP2UEGFRZEZLD6UUBLVEZXJLUAC JTRG7RDQXKPSO4ESGDLSVAT5WIFGKDL424MN6YYCVTKCOR2FTXRQC KSBB33RE2PK5SFN7ZMOTZJQHZB4JYIIUUKWDSD3LSZ5GD465AJHQC X27GNHDV5KPZ5GSH6DCAJMNCEMZLCP7M43JWF2X3O5QWXMOX273AC BVOPAMLSAU4UTV3DUX53OYDMXP2SETAQVUKAYE2OTCVVN4RD7LLQC SHBLLAVHMMHOPCJ5NPGDZQPVRAMPMGXSFEMX7H7BETW6GTRGUUBAC RFE6T5LGBFFNEPHZOPF4UNMFC2L4CGD5TPAMOXDLRPH3TZJ43UBAC 5SHCWE7XPQORSOLY7HGAIK2ODKBFPY4KVXRL2W7X6D4WALU544HQC 7ECJWNVXNO3BKM7B7FIFIRBE77QET5PK2C3XKVQUXCYKHDP3V4UQC JFZNAYJXKCMXYHGCLTRH7Q6TOFGJ4BT6332GONCWVYRLNMDDG3KAC US27ZTX5HCH53SQN2KFSCV2GL2625XL5J3WCDR7D5HLPA7ZSPX5AC 6KIJX24R5RRDR2UQMUAWHF3N6V6DKKL5URYSLB7IT4J5C3RO4G2AC H5REHM3MZKP6SZPMSTMO7SHAVS6W756Q6P2AEJ27R4FZB2IZ2HVAC H3DLVNCJYUJDCILB5LEQDMQDHPRS7ZU66EW3FWXDRBX6WSBUXJTAC FLXJYCRBF2EZIKOHAVPGG3F4GRFJFQVAASAANK5CWTYXZLKFP72QC KZAP6QPOL5XMMV3XVENLTKEIP6ZUE6GJBREZGMLZRAG7IR2WNK7QC 4BXTDMSAHGXAOZI4WQCQQVLADZBE6DLNNITS3EIQFADFVGTLWNHQC G6HJY2V4CSSZF6BPIMRMRAJYRKPLTCBUFTJWZWK3BSNT235CZQ6QC PZL3SZM3U3BYJX2RGYXC6NMBG7WQHFWHSYDYXZ7Q5VZA3EDYVPIQC 5IK6NYKFNY25MHV4SHACJMVGFZBRQICVSOUWNGZFAQ2GO6QUBYNAC QU5I5GCLSKUEKWPQBFPEHHLH3OODK6KSFHDAIDN52U45U6FNTFNAC MWU6FF4KZVEEQU6ACQ6LDWKA2RY4GGBUUJE6Q2KRDLECF4UBA5KQC E6IC7YIKCWI3LIG3DK7VTACIKCMMQWCOYROXXZL5FYHUWJ7CPN4AC TMP2FRIWXSSLCWOODKHRCVVCF26O7IXGB5KERZNOL5P5L26SHKMQC 2G63HKCHG7S6DGWDOHSDF7PXFPD6H4TRKDKIIFCXXAKET6FCWN2AC OEPUOUNBNTHTFZVDXREGBQCKFRCWMVP2MDVK4OA47VK2DBKEWVYAC NDL67SQT5CLURSU5H27MJ5COTEQNU5ZMVNAMD4V2BA3G6MQT5VSQC LQ5QEDVVHVGX67NJZQ46HOSY336VCLN63L3DT6QNSDV6ARVARITAC IGNQFFV767W2N53L634LEZSBJC35OVC3BDLB52RIRAUEFTPX3ZYQC ZNFDFJHGXHSUP3NT5BZSGZPUFYMXCNTJRLSVD6PYF3N6O6ONAWRAC PPJN6SDP3BIWOB5LB3B2F3HEWM4IG7WZMG7JICERVBR7CDMBOPOQC BIVZGPUTQ2C7X6NJQMVIDDO2OYNO4R3GROGQAWBVNSK2HSZ3REOQC OIUIYIV223PEQ47UPM5FKE24OTYCCZRHS2UON4XSEKQWRVZWJCIAC 7Z3YOKCVJE242IDO4HQVOBBLHFOXXCQIBIKDIUXQLTU5LY5QAORQC 6GEU36HWK66LK3IY37HZOTJI5HOXJRUHIEYGYSVSIF57YBUEATRAC CVWQXYKMTLQSUFPTCYR4Q47IDX7TGGYPR2UKXB3NID6YMV3GRYMQC OZ5UBJEKYFW5WXAJ72IKTEZC7Z3FFFNCIBDPIDNM2CLINFSPYTTAC OR5SJ42Y6HYDJL3UTEXMINLNY2T3LYSVJ6FSYFMHP4K4W2RZAMIQC 7YBYT2LQML2PKEO6UO4444AGSASS664UCDXW2YO3ALB7THQHCEBQC JY7BXXOP3EZCDT5RSMVE4Y6IECXGYL4GEBJOZHR7H3Z35XZ3NIVQC W6DC6K4INJQOJYR553ISCKZV7YIOGHEM3FZQPOLAPSZQ3KSJDMRQC 4HPT4SDDNU24OX2P4FDP2KXKINDCJLZEBN2VIEEKWFEVT4TNWXZAC RU7AQO7U4HCWJNQTR2KRGDLLG24WYD47MWIHREV6SIAPCPDQHAWQC N22GPKYTOLZLBGTGDATQDVZ4R5APZEAOIA7L32X4UXBH4XNI7MWAC package Hydra::Controller::View;use strict;use warnings;use base 'Catalyst::Controller';use Hydra::Helper::Nix;use Hydra::Helper::CatalystUtils;sub getView {my ($c, $projectName, $viewName) = @_;my $project = $c->model('DB::Projects')->find($projectName);notFound($c, "Project $projectName doesn't exist.") if !defined $project;$c->stash->{project} = $project;(my $view) = $c->model('DB::Views')->find($projectName, $viewName);notFound($c, "View $viewName doesn't exist.") if !defined $view;$c->stash->{view} = $view;(my $primaryJob) = $view->viewjobs->search({isprimary => 1});#die "View $viewName doesn't have a primary job." if !defined $primaryJob;my $jobs = [$view->viewjobs->search({},{order_by => ["isprimary DESC", "job", "attrs"]})];$c->stash->{jobs} = $jobs;return ($project, $view, $primaryJob, $jobs);}sub updateView {my ($c, $view) = @_;my $viewName = trim $c->request->params->{name};error($c, "Invalid view name: $viewName")unless $viewName =~ /^[[:alpha:]][\w\-]*$/;$view->update({ name => $viewName, description => trim $c->request->params->{description} });$view->viewjobs->delete;foreach my $param (keys %{$c->request->params}) {next unless $param =~ /^job-(\d+)-name$/;my $baseName = $1;my $name = trim $c->request->params->{"job-$baseName-name"};my $description = trim $c->request->params->{"job-$baseName-description"};my $attrs = trim $c->request->params->{"job-$baseName-attrs"};$name =~ /^([\w\-]+):($jobNameRE)$/ or error($c, "Invalid job name: $name");my $jobsetName = $1;my $jobName = $2;error($c, "Jobset `$jobsetName' doesn't exist.")unless $view->project->jobsets->find({name => $jobsetName});# !!! We could check whether the job exists, but that would# require the evaluator to have seen the job, which may not be# the case.$view->viewjobs->create({ jobset => $jobsetName, job => $jobName, description => $description, attrs => $attrs, isprimary => $c->request->params->{"primary"} eq $baseName ? 1 : 0});}error($c, "There must be one primary job.")if $view->viewjobs->search({isprimary => 1})->count != 1;}sub view : Chained('/') PathPart('view') CaptureArgs(2) {my ($self, $c, $projectName, $viewName) = @_;my ($project, $view, $primaryJob, $jobs) = getView($c, $projectName, $viewName);$c->stash->{project} = $project;$c->stash->{view} = $view;$c->stash->{primaryJob} = $primaryJob;$c->stash->{jobs} = $jobs;}sub view_view : Chained('view') PathPart('') Args(0) {my ($self, $c) = @_;$c->stash->{template} = 'view.tt';my $resultsPerPage = 10;my $page = int($c->req->param('page') || "1") || 1;my @results = ();push @results, getViewResult($_, $c->stash->{jobs}) foreachgetPrimaryBuildsForView($c->stash->{project}, $c->stash->{primaryJob}, $page, $resultsPerPage);$c->stash->{baseUri} = $c->uri_for($self->action_for("view_view"), $c->req->captures);$c->stash->{results} = [@results];$c->stash->{page} = $page;$c->stash->{totalResults} = getPrimaryBuildTotal($c->stash->{project}, $c->stash->{primaryJob});$c->stash->{resultsPerPage} = $resultsPerPage;}sub edit : Chained('view') PathPart('edit') Args(0) {my ($self, $c) = @_;requireProjectOwner($c, $c->stash->{project});$c->stash->{template} = 'edit-view.tt';}sub submit : Chained('view') PathPart('submit') Args(0) {my ($self, $c) = @_;requireProjectOwner($c, $c->stash->{project});txn_do($c->model('DB')->schema, sub {updateView($c, $c->stash->{view});});$c->res->redirect($c->uri_for($self->action_for("view_view"), $c->req->captures));}sub latest : Chained('view') PathPart('latest') {my ($self, $c, @args) = @_;# Redirect to the latest result in the view in which every build# is successful.my $latest = getLatestSuccessfulViewResult($c->stash->{project}, $c->stash->{primaryJob}, $c->stash->{jobs}, 0);error($c, "This view set has no successful results yet.") if !defined $latest;$c->res->redirect($c->uri_for($self->action_for("view_view"), $c->req->captures, $latest->id, @args, $c->req->params));}sub latest_finished : Chained('view') PathPart('latest-finished') {my ($self, $c, @args) = @_;# Redirect to the latest result in the view in which every build# is successful *and* where the jobset evaluation has finished# completely.my $latest = getLatestSuccessfulViewResult($c->stash->{project}, $c->stash->{primaryJob}, $c->stash->{jobs}, 1);error($c, "This view set has no successful results yet.") if !defined $latest;$c->res->redirect($c->uri_for($self->action_for("view_view"), $c->req->captures, $latest->id, @args, $c->req->params));}sub result : Chained('view') PathPart('') {my ($self, $c, $id, @args) = @_;$c->stash->{template} = 'view-result.tt';# Note: we don't actually check whether $id is a primary build,# but who cares?my $primaryBuild = $c->stash->{project}->builds->find($id)or error($c, "Build $id doesn't exist.");error($c, "The primary build of this view result did not provide a release name.")unless $result->{releasename};error($c, "A release named `" . $result->{releasename} . "' already exists.")if $c->stash->{project}->releases->find({name => $result->{releasename}});my $release;txn_do($c->model('DB')->schema, sub {$release = $c->stash->{project}->releases->create({ name => $result->{releasename}, timestamp => time});foreach my $job (@{$result->{jobs}}) {$release->releasemembers->create({ build => $job->{build}->id, description => $job->{job}->description});}});$c->res->redirect($c->uri_for($c->controller('Release')->action_for('view'),[$c->stash->{project}->name, $release->name]));}elsif (scalar @args >= 1 && $args[0] eq "eval") {my $eval = $c->stash->{result}->{eval};notFound($c, "This view result has no evaluation.") unless defined $eval;$c->res->redirect($c->uri_for($c->controller('JobsetEval')->action_for("view"),[$eval->id], @args[1..$#args], $c->req->params));}# Provide a redirect to the specified job of this view result# through `http://.../view/$project/$viewName/$viewResult/$jobName'.# Optionally, you can append `-$system' to the $jobName to get a# build for a specific platform.elsif (scalar @args != 0) {my $jobName = shift @args;my $system;if ($jobName =~ /^($jobNameRE)-($systemRE)$/) {$jobName = $1;$system = $2;}(my $build, my @others) =grep { $_->{job}->job eq $jobName && (!defined $system || ($_->{build} && $_->{build}->system eq $system)) }@{$result->{jobs}};notFound($c, "View doesn't have a job named ‘$jobName’" . ($system ? " for ‘$system’" : "") . ".")unless defined $build;error($c, "Job `$jobName' isn't unique.") if @others;return $c->res->redirect($c->uri_for($c->controller('Build')->action_for('build'),[$build->{build}->id], @args));}}1;my $result = getViewResult($primaryBuild, $c->stash->{jobs});$c->stash->{result} = $result;if (scalar @args == 1 && $args[0] eq "release") {requireProjectOwner($c, $c->stash->{project});my %jobNames;$jobNames{$_->{job}->job}++ foreach @{$result->{jobs}};$c->stash->{jobNames} = \%jobNames;if (($c->request->params->{submit} || "") eq "delete") {$c->stash->{view}->delete;$c->res->redirect($c->uri_for($c->controller('Project')->action_for('project'),[$c->stash->{project}->name]));}
sub create_view_submit : Chained('projectChain') PathPart('create-view/submit') Args(0) {my ($self, $c) = @_;requireProjectOwner($c, $c->stash->{project});my $viewName = $c->request->params->{name};
$c->res->redirect($c->uri_for($c->controller('View')->action_for('view_view'),[$c->stash->{project}->name, $view->name]));}sub create_view : Chained('projectChain') PathPart('create-view') Args(0) {my ($self, $c) = @_;requireProjectOwner($c, $c->stash->{project});$c->stash->{template} = 'edit-view.tt';$c->stash->{create} = 1;}
use utf8;package Hydra::Schema::ViewJobs;# Created by DBIx::Class::Schema::Loader# DO NOT MODIFY THE FIRST PART OF THIS FILE=head1 NAMEHydra::Schema::ViewJobs=cutuse 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<ViewJobs>=cut__PACKAGE__->table("ViewJobs");=head1 ACCESSORS=head2 projectdata_type: 'text'is_foreign_key: 1is_nullable: 0=head2 view_data_type: 'text'is_foreign_key: 1is_nullable: 0=head2 jobdata_type: 'text'is_nullable: 0=head2 attrsdata_type: 'text'is_nullable: 0=head2 isprimarydata_type: 'integer'default_value: 0is_nullable: 0=head2 descriptiondata_type: 'text'is_nullable: 1=head2 jobsetdata_type: 'text'is_nullable: 0=head2 autoreleasedata_type: 'integer'default_value: 0is_nullable: 0=cut__PACKAGE__->add_columns("project",{ data_type => "text", is_foreign_key => 1, is_nullable => 0 },"view_",{ data_type => "text", is_foreign_key => 1, is_nullable => 0 },"job",{ data_type => "text", is_nullable => 0 },"attrs",{ data_type => "text", is_nullable => 0 },"isprimary",{ data_type => "integer", default_value => 0, is_nullable => 0 },"description",{ data_type => "text", is_nullable => 1 },"jobset",{ data_type => "text", is_nullable => 0 },"autorelease",{ data_type => "integer", default_value => 0, is_nullable => 0 },);=head1 PRIMARY KEY=over 4=item * L</project>=item * L</view_>=item * L</job>=item * L</attrs>=back=cut__PACKAGE__->set_primary_key("project", "view_", "job", "attrs");=head1 RELATIONS=head2 projectType: belongs_toRelated object: L<Hydra::Schema::Projects>=cut__PACKAGE__->belongs_to("project","Hydra::Schema::Projects",{ name => "project" },{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },);=head2 viewType: belongs_toRelated object: L<Hydra::Schema::Views>=cut__PACKAGE__->belongs_to("view","Hydra::Schema::Views",{ name => "view_", project => "project" },{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },);# Created by DBIx::Class::Schema::Loader v0.07033 @ 2013-06-13 01:54:50# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hz912vBfYw0rHslBPqJW2w1;
use utf8;package Hydra::Schema::Views;# Created by DBIx::Class::Schema::Loader# DO NOT MODIFY THE FIRST PART OF THIS FILE=head1 NAMEHydra::Schema::Views=cutuse 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<Views>=cut__PACKAGE__->table("Views");=head1 ACCESSORS=head2 projectdata_type: 'text'is_foreign_key: 1is_nullable: 0=head2 namedata_type: 'text'is_nullable: 0=head2 descriptiondata_type: 'text'is_nullable: 1=head2 keepdata_type: 'integer'default_value: 0is_nullable: 0=cut__PACKAGE__->add_columns("project",{ data_type => "text", is_foreign_key => 1, is_nullable => 0 },"name",{ data_type => "text", is_nullable => 0 },"description",{ data_type => "text", is_nullable => 1 },"keep",{ data_type => "integer", default_value => 0, is_nullable => 0 },);=head1 PRIMARY KEY=over 4=item * L</project>=item * L</name>=back=cut__PACKAGE__->set_primary_key("project", "name");=head1 RELATIONS=head2 projectType: belongs_toRelated object: L<Hydra::Schema::Projects>=cut__PACKAGE__->belongs_to("project","Hydra::Schema::Projects",{ name => "project" },{ is_deferrable => 0, on_delete => "CASCADE", on_update => "CASCADE" },);=head2 viewjobsType: has_manyRelated object: L<Hydra::Schema::ViewJobs>=cut__PACKAGE__->has_many("viewjobs","Hydra::Schema::ViewJobs",{ "foreign.project" => "self.project", "foreign.view_" => "self.name" },undef,);# Created by DBIx::Class::Schema::Loader v0.07033 @ 2013-06-13 01:54:50# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:U23GZ3k5KZk2go6j2LYLHA1;
{ "foreign.project" => "self.name" },undef,);=head2 viewjobsType: has_manyRelated object: L<Hydra::Schema::ViewJobs>=cut__PACKAGE__->has_many("viewjobs","Hydra::Schema::ViewJobs",{ "foreign.project" => "self.name" },undef,);=head2 viewsType: has_manyRelated object: L<Hydra::Schema::Views>=cut__PACKAGE__->has_many("views","Hydra::Schema::Views",
# Created by DBIx::Class::Schema::Loader v0.07033 @ 2014-04-23 22:48:21# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:l8eN9UAavdqnL7Sjv4rmFw
# Created by DBIx::Class::Schema::Loader v0.07033 @ 2014-04-23 23:13:08# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:fkd9ruEoVSBGIktmAj4u4g
[% releaseName = (result.releasename || "(No name)") %][% WRAPPER layout.tt title="View $releaseName" %][% PROCESS common.tt %][% PROCESS "product-list.tt" %][% USE HTML %]<p><em>Finished building on [% INCLUDE renderDateTime timestamp = result.timestamp %].</em></p>[% IF result.status == 1 %]<p class="error">Note: One or more of the jobs in the view did not build correctly. See below for details.</p>[% ELSIF result.status == 2 %]<p class="error">Note: One or more of the jobs in the view have not been built (yet). See below for details.</p>[% END %][% FOREACH j IN result.jobs %]<h2>[% IF j.build %]<a href="[% c.uri_for('/build' j.build.id) %]">[% END %][% INCLUDE renderViewJobName job=j.job %][% IF j.build %]</a>[% END %]</h2>[% IF j.build %][% IF j.build.buildstatus == 0 %][% IF j.build.buildproducts %][% p = jobNames.${j.job.job} > 1 ? "-${j.build.system}" : "";INCLUDE renderProductList build=j.build latestRoot=['/view' project.name view.name 'latest' "${j.job.job}${p}"]%][% ELSE %]<p><em>Succeeded.</em></p>[% END %][% ELSE %]<p class="error">Build failed</p>[% END %][% ELSE %]<p class="error">Build not (yet) performed.</p>[% END %]<br />[% END %][% END %][% IF c.user_exists %]<p><a class="btn" href="[% c.uri_for('/view' project.name view.name result.id 'release') %]">Release</a></p>[% END %]
[% WRAPPER layout.tt title=(create ? "New view" : "View $project.name:$view.name") %][% PROCESS common.tt %][% USE HTML %][% BLOCK renderJob %]<tr id="[% id %]" ><td><button type="button" class="btn btn-warning" onclick='$(this).parents("tr").remove()'><i class="icon-trash icon-white"></i></button></td><td><input type="radio" id="[% "$baseName-primary" %]" name="primary" [% IF job.isprimary %]checked="checked" [% END %] [% HTML.attributes(value => "$n") %] /></td><td><input type="text" class="string" [% HTML.attributes(id => "$baseName-name", name => "$baseName-name", value => "$job.jobset:$job.job") %] /></td><td><input type="text" class="string" [% HTML.attributes(id => "$baseName-description", name => "$baseName-description", value => job.description) %] /></td><td><input type="text" class="string" [% HTML.attributes(id => "$baseName-attrs", name => "$baseName-attrs", value => job.attrs) %] /></td></tr>[% END %]<form class="form-horizontal" action="[% IF create %][% c.uri_for('/project' project.name 'create-view/submit') %][% ELSE %][% c.uri_for('/view' project.name view.name 'submit') %][% END %]" method="post"><fieldset><div class="control-group"><label class="control-label">Identifier</label><div class="controls"><input type="text" class="span3" name="name" [% HTML.attributes(value => view.name) %]/></div></div><div class="control-group"><label class="control-label">Description</label><div class="controls"><input type="text" class="span3" name="description" [% HTML.attributes(value => view.description) %]/></div></div><table class="table table-condensed table-striped"><thead><tr><th></th><th>Primary job</th><th>Job name</th><th>Description</th><th>Constraint</th></tr></thead><tbody>[% n = 0 %][% FOREACH j IN jobs %][% INCLUDE renderJob baseName="job-$n" job=j %][% n = n + 1 %][% END %]</tbody></table><div class="form-actions"><button type="submit" class="btn btn-primary"><i class="icon-ok icon-white"></i>[%IF create %]Create[% ELSE %]Apply changes[% END %]</button>[% IF !create %]<button id="delete-view" type="submit" class="btn btn-danger" name="submit" value="delete"><i class="icon-trash icon-white"></i>Delete this view</button><script type="text/javascript">$("#delete-view").click(function() {return confirm("Are you sure you want to delete this view?");});</script>[% END %]</div></form><table class="template"> <!-- dummy wrapper needed because “hidden” trs are visible anyway -->[% INCLUDE renderJob job="" id="job-template" baseName="job-template" %]</table><script type="text/javascript">$(document).ready(function() {var id = [% n %];$(".add-job").click(function() {var newnr = id++;var newid = "job-" + newnr;var x = $("#job-template").clone(true).attr("id", "").insertBefore($(this).parents("tr")).show();$("#job-template-name", x).attr("name", newid + "-name");$("#job-template-description", x).attr("name", newid + "-description");$("#job-template-attrs", x).attr("name", newid + "-attrs");$("#job-template-primary", x).attr("value", newnr);return false;});});</script>[% END %]<tr><td colspan="5" style="text-align: center;"><button type="button" class="add-job btn btn-success"><i class="icon-plus icon-white"></i> Add a job</button></td></tr>
[% WRAPPER layout.tt title="View $view.project.name:$view.name" %][% PROCESS common.tt %][% USE HTML %]<p><a class="btn" href="[% c.uri_for('/view' project.name view.name "edit") %]"><i class="icon-edit"></i> Edit</a><a class="btn" href="[% c.uri_for('/view' project.name view.name "latest") %]"><i class="icon-share-alt"></i> Latest</a></p><p>Showing results [% (page - 1) * resultsPerPage + 1 %] - [% (page - 1) * resultsPerPage + results.size %] out of [% totalResults %].</p><table class="table table-condensed table-striped clickable-rows"><thead><tr><th></th><th>#</th><th>Name</th><th>Date</th>[% FOREACH j IN jobs %]<th class="releaseSetJobName">[% INCLUDE renderViewJobName job=j %]</th>[% END %]</tr></thead><tbody>[% FOREACH result IN results %]<tr><td>[% IF result.status == 0 %]<img src="[% c.uri_for("/static/images/checkmark_16.png") %]" />[% ELSIF result.status == 1 %]<img src="[% c.uri_for("/static/images/error_16.png") %]" />[% ELSIF result.status == 2 %]<img src="[% c.uri_for("/static/images/help_16.png") %]" />[% END %]</td><td><a class="row-link" href="[% c.uri_for('/view' project.name view.name result.id) %]">[% result.id %]</a></td><td>[% IF result.releasename %]<tt>[% result.releasename %]</tt>[% ELSE %]<em>No name</em>[% END %]</td><td>[% INCLUDE renderDateTime timestamp=result.timestamp %]</td>[% FOREACH j IN result.jobs %]<td class="centered">[% IF j.build %]<a href="[% c.uri_for('/build' j.build.id) %]">[% IF j.build.get_column('buildstatus') == 0 %]<img src="[% c.uri_for("/static/images/checkmark_16.png") %]" />[% ELSE %]<img src="[% c.uri_for("/static/images/error_16.png") %]" />[% END %]</a>[% END %]</td>[% END %]</tr>[% END %]</tbody></table>[% END %]<ul class="pager">[% IF page > 1 %]<li class="previous"><a href="[% "$baseUri?page="; (page - 1) %]">Prev</a></li>[% END %][% IF page * resultsPerPage < totalResults %]<li class="next"><a href="[% "$baseUri?page="; (page + 1) %]">Next</a></li>[% END %]</ul><!--[<a href="[% "$baseUri?page=1" %]">First</a>][% IF page > 1 %][<a href="[% "$baseUri?page="; (page - 1) %]">Prev</a>][% END %][% IF page * resultsPerPage < totalResults %][<a href="[% "$baseUri?page="; (page + 1) %]">Next</a>][% END %][<a href="[% "$baseUri?page="; (totalResults - 1) div resultsPerPage + 1 %]">Last</a>]</p>--><p>
<div id="tabs-views" class="tab-pane">[% IF views.size > 0 %]<p>Project <tt>[% project.name %]</tt> has the following views:</p>
<ul>[% FOREACH view IN views %]<li><a href="[% c.uri_for('/view' project.name view.name) %]"><tt>[% view.name %]</tt></a></li>[% END %]</ul>[% ELSE %]<p>Project <tt>[% project.name %]</tt> has no views.</p>[% END %]<!--<p><a class="btn" href="[% c.uri_for('/project' project.name 'create-view') %]"><i class="icon-plus"></i> Create a new view</a></p>--></div>
);-- Views are a mechanism to automatically group related builds-- together. A view definition consists of a build of some "primary"-- job, plus all builds of the other jobs named in ViewJobs that have-- that build as an input. If there are multiple builds matching a-- ViewJob, then we take the oldest successful build, or the oldest-- unsuccessful build if there is no successful build.create table Views (project text not null,name text not null,description text,-- If true, don't garbage-collect builds included in this view.keep integer not null default 0,primary key (project, name),foreign key (project) references Projects(name) on delete cascade on update cascade
create table ViewJobs (project text not null,view_ text not null,job text not null,-- A constraint on the job consisting of `name=value' pairs,-- e.g. "system=i686-linux officialRelease=true". Should really-- be a separate table but I'm lazy.attrs text not null,-- If set, this is the primary job for the view. There can be-- only one such job per view.isPrimary integer not null default 0,description text,jobset text not null,-- If set, once there is a successful build for every job-- associated with a build of the view's primary job, that set of-- builds is automatically added as a release to the Releases-- table.autoRelease integer not null default 0,primary key (project, view_, job, attrs),foreign key (project) references Projects(name) on delete cascade on update cascade,foreign key (project, view_) references Views(project, name) on delete cascade on update cascade);
drop table ViewJobs;drop table Views;