Skip to content

Commit

Permalink
Refactored runs listing.
Browse files Browse the repository at this point in the history
Added a new optional parameter to methods
returning lists of runs and run count - the name of
the manufacturer. If this name is undefined in the
parameters hash, it defaults to 'Illumina'.

To avoid code repetition, consolidated queries for
listing and counting runs, which wer epreviously
in six different places.

Simplified the logic of retrieving cached lists
and counts of runs vs computing new values.
  • Loading branch information
mgcam committed Jan 8, 2025
1 parent a52ccab commit d391bbc
Showing 5 changed files with 214 additions and 278 deletions.
158 changes: 92 additions & 66 deletions lib/npg/model/run.pm
Original file line number Diff line number Diff line change
@@ -34,6 +34,8 @@ Readonly::Scalar our $DEFAULT_SUMMARY_DAYS => 14;
Readonly::Scalar my $FOLDER_GLOB_INDEX => 2;
Readonly::Scalar my $PADDING => 4;
Readonly::Hash our %TEAMS => ('2' => 'RAD', '1' => 'A',);
Readonly::Scalar my $DEFAULT_MANUFACTURER_NAME => q{Illumina};
Readonly::Scalar my $SHOW_ALL_PARAM_VALUE => q{all};

__PACKAGE__->mk_accessors(fields());
__PACKAGE__->has_a([qw(instrument instrument_format)]);
@@ -133,83 +135,92 @@ sub end {

sub runs {
my ( $self, $params ) = @_;
# The run view might have cached the data.
return $self->{runs} ? $self->{runs} : $self->list_runs($params);
}

$params->{id_instrument_format} ||= q{all};

# once we have determined this, we will set the runs to be what has been requested for the templates benefit
if ( $self->{runs} && ref $self->{runs} eq q{ARRAY} ) {
return $self->{runs};
}

if ( ! $self->{runs} || ref $self->{runs} ne q{HASH} ) {
$self->{runs} = {};
}

if ( $self->{runs}->{ $params->{id_instrument_format} } ) {
return $self->{runs}->{ $params->{id_instrument_format} };
}

my $pkg = ref $self;
my $query = qq[SELECT @{[join q[, ], $pkg->fields()]}
FROM @{[$pkg->table()]}];

if ( $params->{id_instrument} && $params->{id_instrument} =~ /\d+/xms ) {
$query .= qq[ WHERE id_instrument = $params->{id_instrument}];
} else {
if ( $params->{id_instrument_format} ne q{all} && $params->{id_instrument_format} =~ /\A\d+\z/xms ) {
$query .= qq[ WHERE id_instrument_format = $params->{id_instrument_format}];
}
}
$query .= q[ ORDER BY id_run DESC];
sub list_runs {
my ( $self, $params ) = @_;

if ( $params ) {
$query = $self->util->driver->bounded_select( $query,
my $select_count = 0;
my $query = $self->_create_query($select_count, $params);
$query .= q[ ORDER BY r.id_run DESC];
$query = $self->util->driver->bounded_select( $query,
$params->{len},
$params->{start});
}

$self->{runs}->{ $params->{id_instrument_format} } = $self->gen_getarray( $pkg, $query );
return $self->{runs}->{ $params->{id_instrument_format} };
my $pkg = ref $self;
return $self->gen_getarray($pkg, $query);
}

sub count_runs {
my ( $self, $params ) = @_;
$params ||= {};
$params->{id_instrument_format} ||= q{all};

# once we have determined this, we will set the runs to be what has been requested for the templates benefit
if ( defined $self->{count_runs} && ! ref $self->{count_runs} ) {
return $self->{count_runs};
}
# The run view might have cached the data.
return defined $self->{count_runs} ? $self->{count_runs} :
$self->get_runs_count($params);
}

if ( ! $self->{count_runs} || ref $self->{count_runs} ne q{HASH} ) {
$self->{count_runs} = {};
}
sub get_runs_count {
my ( $self, $params ) = @_;

if ( defined $self->{count_runs}->{ $params->{id_instrument_format} } ) {
return $self->{count_runs}->{ $params->{id_instrument_format} };
$params ||= {};
my $select_count = 1;
my $query = $self->_create_query($select_count, $params);
my $ref = $self->util->dbh->selectall_arrayref( $query );
if ( defined $ref->[0] && defined $ref->[0]->[0] ) {
return $ref->[0]->[0];
}

my $pkg = ref $self;
my $query = qq[SELECT COUNT(*)
FROM @{[$pkg->table()]}];
return;
}

if ( $params->{id_instrument} && $params->{id_instrument} =~ /\d+/xms ) {
$query .= qq[ WHERE id_instrument = $params->{id_instrument}];
sub _create_query {
my ($self, $select_count, $params) = @_;

my $id_instr_format = $params->{id_instrument_format};
$id_instr_format ||= $SHOW_ALL_PARAM_VALUE;
my $manufacturer_name = $params->{manufacturer};
$manufacturer_name ||= $DEFAULT_MANUFACTURER_NAME;
my $id_instr = $params->{id_instrument};
my $id_status_dict = $params->{id_run_status_dict};

my $pkg = ref $self;
my $query = sprintf 'SELECT %s FROM %s AS r',
$select_count ? q[COUNT(*)] : join(q[, ], map { q[r.] . $_ } $pkg->fields()),
$pkg->table();

my @where = ();
# If run info for a particular instrument is requested, disregard the
# instrument format and the manufacturer.
if ( $id_instr && $id_instr =~ /\d+/xms ) {
push @where, qq[r.id_instrument = $id_instr];
} else {
if ( $params->{id_instrument_format} ne q{all} && $params->{id_instrument_format} =~ /\A\d+\z/xms ) {
$query .= qq[ WHERE id_instrument_format = $params->{id_instrument_format}];
# If run info for a particular instrument format is requested, disregard
# the manufacturer.
if ( $id_instr_format =~ /\A\d+\z/xms ) {
push @where, qq[r.id_instrument_format = $id_instr_format];
}
# If runs from a particular manufacturer are requested, select
# on manufacturer name.
if ( $manufacturer_name ne $SHOW_ALL_PARAM_VALUE ) {
$query .= ' JOIN instrument_format AS inf' .
' ON r.id_instrument_format=inf.id_instrument_format' .
' JOIN manufacturer AS m' .
' ON inf.id_manufacturer=m.id_manufacturer';
push @where, qq[m.name = '$manufacturer_name'];
}
}

my $ref = $self->util->dbh->selectall_arrayref( $query );
if( defined $ref->[0] &&
defined $ref->[0]->[0] ) {
$self->{count_runs}->{ $params->{id_instrument_format} } = $ref->[0]->[0];
return $ref->[0]->[0];
# Filter by current run status.
if ( $id_status_dict && ($id_status_dict ne $SHOW_ALL_PARAM_VALUE) ) {
$query .= ' JOIN run_status AS rs ON r.id_run=rs.id_run';
push @where, qq[rs.id_run_status_dict=$id_status_dict AND rs.iscurrent=1];
}

return;
if (@where) {
$query .= ' WHERE ' . join ' AND ', @where;
}

return $query;
}

sub current_run_status {
@@ -1053,16 +1064,31 @@ npg::model::run
=head2 runs - arrayref of all npg::model::runs
my $arAllRuns = $oRun->runs();
my $arRuns = $oRun->runs($params);
my $arRunsBounded = $oRun->runs({
len => 10,
start => 20,
};
Returns a list of cached run models or retrieves a new list in accordance with
the parameters of the query, see C<get_runs>. Bounds the retrieved list
according to C<start> and C<len> parameters.
=head2 list_runs - arrayref of all npg::model::runs
my $arRuns = $oRun->list_runs($params);
Retrieves and returns a list or run models in accordance with the parameters
of the query.
=head2 count_runs
my $iRunCount = $oRun->count_runs($params);
Returns a cached value or retrieves a new one in accordance with
the parameters of the query, see C<get_runs_count>.
=head2 get_runs_count
=head2 count_runs - count of runs for this instrument
my $iRunCount = $oRun->count_runs($params);
my $iRunCount = $oRun->count_runs();
Returns the cout of runs according to the parameters of the query.
=head2 runs_on_batch
@@ -1251,7 +1277,7 @@ $instruments is undefined
=head1 LICENSE AND COPYRIGHT
Copyright (C) 2006-2012,2013,2014,2015,2016,2017,2020, 2021 Genome Research Ltd.
Copyright (C) 2006-2012, 2013,2014,2015,2016,2017,2020,2021,2022,2025 Genome Research Ltd.
This file is part of NPG.
93 changes: 9 additions & 84 deletions lib/npg/model/run_status_dict.pm
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#########
# Author: rmp
# Created: 2006-10-31
#
package npg::model::run_status_dict;

use strict;
use warnings;
use base qw(npg::model);
@@ -43,70 +40,6 @@ sub init {
return 1;
}

sub runs {
my ($self, $params ) = @_;
$params ||= {};
$params->{id_instrument_format} ||= q{all};

my $pkg = 'npg::model::run';
my $query = qq(SELECT @{[join q(, ), map { "r.$_" } $pkg->fields()]}
FROM @{[$pkg->table()]} r,
run_status rs
WHERE rs.id_run = r.id_run
AND rs.iscurrent = 1
AND rs.id_run_status_dict = ?);

if ( $params->{id_instrument} && $params->{id_instrument} =~ /\d+/xms ) {
$query .= qq[ AND id_instrument = $params->{id_instrument}];
} else {
if ( $params->{id_instrument_format} ne q{all} && $params->{id_instrument_format} =~ /\A\d+\z/xms ) {
$query .= qq[ AND r.id_instrument_format = $params->{id_instrument_format}];
}
}
$query .= q( ORDER BY r.id_run DESC);

$query = $self->util->driver->bounded_select($query,
$params->{len},
$params->{start});

return $self->gen_getarray($pkg, $query, $self->id_run_status_dict());
}

sub count_runs {
my ( $self, $params ) = @_;
$params ||= {};
$params->{id_instrument_format} ||= q{all};
$self->{count_runs} ||= {};

if ( ! defined $self->{count_runs}->{id_instrument_format} ) {

my $pkg = 'npg::model::run';
my $query = qq(SELECT COUNT(*)
FROM @{[$pkg->table()]} r,
run_status rs
WHERE rs.id_run = r.id_run
AND rs.iscurrent = 1
AND rs.id_run_status_dict = ?);

if ( $params->{id_instrument} && $params->{id_instrument} =~ /\d+/xms ) {
$query .= qq[ AND id_instrument = $params->{id_instrument}];
} else {
if ( $params->{id_instrument_format} ne q{all} && $params->{id_instrument_format} =~ /\A\d+\z/xms ) {
$query .= qq[ AND r.id_instrument_format = $params->{id_instrument_format}];
}
}

my $ref = $self->util->dbh->selectall_arrayref($query, {}, $self->id_run_status_dict());

if ( defined $ref->[0] &&
defined $ref->[0]->[0] ) {
$self->{count_runs}->{ $params->{id_instrument_format} } = $ref->[0]->[0];
}
}

return $self->{count_runs}->{ $params->{id_instrument_format} } || 0;
}

sub run_status_dicts_sorted {
my ( $self ) = @_;

@@ -155,20 +88,6 @@ npg::model::run_status_dict
my $arRunStatusDicts = $oRunStatusDict->run_status_dicts();
=head2 runs - arrayref of npg::model::runs with a current status having this id_run_status_dict
my $arRuns = $oRunStatusDict->runs();
Takes an optional hash of params, id_instrument_format => (all,1,2,3..) (defaults to all)
If this is given, the runs returned will only be for instruments of that format
=head2 count_runs - Count the runs with this rsd as their current status
my $iCountRuns = $oRunStatusDict->count_runs();
Takes an optional hash of params, id_instrument_format => (all,1,2,3..) (defaults to all)
If this is given, the count of runs returned will only be for instruments of that format
=head2 run_status_dicts_sorted
Use instead of generated run_status_dicts to get a temporal ordered, current list
@@ -185,11 +104,17 @@ Use instead of generated run_status_dicts to get a temporal ordered, current lis
=head1 AUTHOR
Roger Pettett, E<lt>[email protected]E<gt>
=over
=item Roger Pettett
=item Marina Gourtovaia
=back
=head1 LICENSE AND COPYRIGHT
Copyright (C) 2008 GRL, by Roger Pettett
Copyright (C) 2006-2012,2013,2014,2025 Genome Research Ltd.
This file is part of NPG.
Loading

0 comments on commit d391bbc

Please sign in to comment.