# updates hilis4.request_storage dna concentrations from xl src in # "I:\MiSeq\Myeloid\HILIS concentration upload" and adds comment to # request_lab_test_history # usage: perl storage_dna_update.pl -f [-t] MiSeq_Myeloid_20xx_xx_upload.xlsx use Getopt::Std; getopts('f:t'); # filename, testing our($opt_f, $opt_t); # warn $opt_t; exit; use lib '/home/raj/perl-lib'; use FindBin qw($Bin); # warn $Bin; use Data::Printer alias => 'p', use_prototypes => 1; use Math::Round qw(round); use Spreadsheet::Read; use Local::DB; use Modern::Perl; use IO::All; #=============================================================================== my $db = 'hilis4'; my $src = $opt_f or die 'require source filename'; # p $src; my $JUST_TESTING = $opt_t || 0; # prints update but doesn't do it #=============================================================================== my $dbix = Local::DB->dbix({ dbname => 'hilis4' }); $dbix->lc_columns = 0; # vialId my $xls = ReadData($Bin . '/' . $src); # p $xls; my $log = $src =~ s/xlsx$/log/r; # p $log; # r = non-destructive; my $sheet = $xls->[1]; # p $sheet; # 1st sheet # rows() not exported so call as fully qualified method: my @rows = Spreadsheet::Read::rows($sheet); # p @rows; # AoA my $headers = shift @rows; $_ =~ s/\s/_/ for @$headers; $_ =~ s/(\w+)/lc $1/eg for @$headers; # p $headers; exit; my $request_query = q!select r.id, p.last_name from hilis4.requests r join patient_case pc on r.patient_case_id = pc.id join patients p on pc.patient_id = p.id where request_number = ? and year = ?!; my $storage_query = qq!select vialId, concentration from $db.request_storage where request_id = ? and specimen_id = ?!; my $specimen_map = $dbix->select('specimens', ['sample_code','id'])->map; # p $specimen_map; my $user_id; # set inside block my $i = 0; # update success counter ROW: for my $row (@rows) { # arrayref my $data = _to_hash($row); # p $data; next; # get user - may only occur once in spreadsheet, needs to be 1st row: if ( my $user = trim($data->{user}) ) { $user_id ||= $dbix->select('users', 'id', { username => $user})->value or die "cannot find user_id for user $user"; # p $user_id; } # check we have a valid user_id: defined $user_id || die 'cannot find a valid user_id'; # get request_number & year from sample col: my ($req_num, $yr) = $data->{sample} =~ m!H?(\d+)/(\d{2})!; # p $req_num; p $yr; # get request_id & last_name from hilis4 db: my ($req_id, $last_name) = $dbix->query($request_query, $req_num, $yr + 2000)->row; # p $req_id; p $last_name; unless ( lc $last_name eq lc trim($data->{last_name}) ) { my $msg = sprintf "request %s/%s last name mismatch (%s, %s)", $req_num, $yr, $last_name, $data->{last_name}; $JUST_TESTING ? say $msg : io($Bin . '/'. $log)->append($msg . "\n"); next ROW; } # get specimen from specimen col & get specimen_id from hilis4: my $specimen = trim($data->{specimen}); # p $specimen; my $specimen_id = $specimen_map->{$specimen} or say qq!don't recognise "$specimen"! and next ROW; # get concentration result from xl col: my $new_value = round($data->{concentration}); # p $concentration; # get db request_storage vialId & current value for request_id/specimen: my ($vialId, $old_value) = $dbix->query($storage_query, $req_id, $specimen_id)->row; unless ( $vialId && $old_value ) { my $msg = sprintf "request %s/%s does not have %s stored", $req_num, $yr, $specimen; $JUST_TESTING ? say $msg : io($Bin . '/'. $log)->append($msg . "\n"); next ROW; } # end of block if just testing: say "will update $req_num/$yr $vialId/$specimen $old_value -> $new_value" and next ROW if $JUST_TESTING; { # update request_storage table: my $result = $dbix->update("$db.request_storage", { concentration => $new_value }, { vialId => $vialId, part_number => 1 }); unless ( $result->rows ) { my $msg = sprintf "request %s/%s failed to update with %s/%s", $req_num, $yr, $specimen, $new_value; $JUST_TESTING ? say $msg : io($Bin . '/'. $log)->append($msg . "\n"); next ROW; } my $msg = sprintf "updated request %s/%s %s DNA concentration from %s to %s", $req_num, $yr, $specimen, $old_value, $new_value; io($Bin . '/'. $log)->append($msg . "\n"); $i += $result->rows; } { # do request_lab_test_history: my %h = ( request_id => $req_id, user_id => $user_id, action => "batch-updated $specimen storage vial DNA concentration value", ); my $result = $dbix->insert("$db.request_lab_test_history", \%h); unless ( $result->rows ) { my $msg = sprintf "failed to update request_lab_test_history for request %s/%s", $req_num, $yr; } } } say sprintf "updated %s of %s rows", $i, scalar @rows; sub trim { local $_ = shift || return; $_ =~ s/^\s+|\s+$//g; return $_; } sub _to_hash { my $ref = shift; # p $ref; # arrayref my %h; my $i = 0; for (@$headers) { # p $_; $h{$_} = $ref->[$i++]; } # p %h; return \%h; }