RSS Git Download  Clone
Raw Blame History
package RequestForm::DB;

use LIMS::Local::QueryLibrary;
use DateTime::Format::MySQL;
use LIMS::Local::Utils;
use Clone 'clone';
use Data::Dumper;
use Path::Tiny;
use FindBin;

use lib '/home/raj/perl-lib';
use Local::DB;

use RequestForm::Test; # test_schema() for test scripts
use RequestForm::Class; # provides Moo, Local::MooX::Types & LIMS::Local::Debug::p

has dbname  => ( is => 'ro', isa => String, required => 1 ); # uclh, hilis4, etc
has sql_lib => ( is => 'lazy' ); # returns SQL::Library obj
has dbix    => ( is => 'lazy' ); # returns DBIx::Simple object

sub _build_dbix {
    my $self = shift;

    my $db = $self->dbname; # dbname = uclh, leeds, etc
    $db =~ s/leeds/hilis4/; # leeds -> hilis4 symlink doesn't work on innodb tables

    my $dbix = ( $db eq 'test' ) # return in memory sqlite dbix object
        ? Local::DB->dbix({ dsn => 'dbi:SQLite:dbname=:memory:' })
        : Local::DB->dbix($db);
    return $dbix;
}

sub _build_sql_lib {
	my $lib = path($FindBin::Bin, '..', 'sql.lib')->realpath;
	LIMS::Local::QueryLibrary->new({ lib => $lib });
}

sub save_params {
    my $self = shift;
    my $vars = shift; # p $vars;

    # get field names from request_form table:
    my $cols = $self->get_cols('request_form'); # p $cols;
    my %h = map +($_ => $vars->{$_}), @$cols; # p %h;

    my $db = $self->dbix();
    $db->insert('request_form', \%h);
}

sub bcr_abl_monitoring { # bcr_abl_monitoring table:
    my $self = shift;
    my $vars = shift; # p $vars;

	# clone $vars to localise datetime transformation of date cols:
	my $data = clone($vars);
	
	my $db = $self->dbix();

	my $datetime_func =
		sub { LIMS::Local::Utils::to_datetime_using_datecalc(@_) };
	my $tbl  = 'bcr_abl_monitoring';
	my $cols = $self->get_cols($tbl); # p $cols;
	
	my @date_cols = grep $_ =~ /date/, @$cols; # p @date_cols;

	# this action changes date_col values so need to use cloned vars:
	$data->{$_} = &$datetime_func($data->{$_})->ymd	for @date_cols; # p $data;

	my %row_id = ( nhs_number => $data->{nhs_number} );
	if ( $db->select($tbl, 1, \%row_id)->list ) { # update:
		my %h = map +($_ => $data->{$_}), @date_cols;
		$db->update($tbl, \%h, \%row_id);
	}
	else { # insert new:
		my %h = map +($_ => $data->{$_}), @$cols; # p \%h;
		$db->insert($tbl, \%h);
	} # my $ref = $db->select($tbl, '*')->hash; warn Dumper $ref;
}

sub search_patient {
    my ($self, $nhs_number) = @_; # p $nhs_number;

    my $db = $self->dbix();
    my $data = $db->select('patients', '*', { nhs_number => $nhs_number })->hash;
    return $data;
}

sub get_referral_sources {
    my ($self, $str) = @_; # part of referral_location (string)

    my $db  = $self->dbix();
	my $lib = $self->sql_lib;
	my $sql = $lib->retr('referral_sources');

    my $data = $db->query( $sql, $str )->hashes; # p $vars;
    return $data;
}

sub get_previous_cml_monitoring {
    my ($self, $nhs_number) = @_;

    my $db  = $self->dbix();
	my $lib = $self->sql_lib;
	my $sql = $lib->retr('previous_cml_monitoring');

    my $query = $db->query( $sql, $nhs_number );

    my (@data, $last_result);
    # get bcr-abl results in reverse chronological order:
    while ( my $ref = $query->hash ) { # p $ref;
        # registration date to DT object:
        my $reg_date = DateTime::Format::MySQL->parse_date($ref->{registered});
        # extract bcr-abl:abl ratio if exists:
        my ($ratio)  = $ref->{result} =~ /(BCR-ABL : ABL ratio = .*%)/;

        # date of last result is reg date of most recent bcr-abl ratio:
        $last_result = $reg_date if ( $ratio and ! $last_result );

        # set result to bcr-abl:abl ratio, otherwise keep original:
        push @data, {
            registered => $reg_date,
            result     => $ratio || $ref->{result},
        };
    }
    my %h = (
        date_last => $last_result,
        results   => \@data,
    );

    { # get date of diagnosis & date 1st-line tx (if exists):
        my @cols = qw( diagnosis_date first_line_date );
        my $dates = $db->select( 'bcr_abl_monitoring', \@cols,
            { nhs_number => $nhs_number } )->hash;
        # dates to datetime objects:
        map {
            $dates->{$_} = DateTime::Format::MySQL->parse_date($dates->{$_});
        } grep $dates->{$_}, @cols;
        $h{dates} = $dates;
    } # p %h;
    return \%h;
}

sub get_userid {
    my ($self, $username) = @_;

    my $db = $self->dbix();
    $db->select('users', 'id', { username => $username })->into(my $user_id);
    return $user_id;
}

sub get_cols {
	my ($self, $table) = @_;

    my $db = $self->dbname;

	my $meta = $db eq 'test'
        ? $self->get_meta_for_sqlite($table)
        : $self->get_meta_for_mysql($table); # p $meta;

	return [ keys %$meta ];
}

sub get_meta_for_mysql {
	my ($self, $table) = @_;

	my $dbh = $self->dbix;

	my $t = $dbh->query("show columns from $table")->hashes; # p $t;
	my %meta = map { $_->{field} => $_ } @$t; # p %meta;
	return \%meta;
}

sub get_meta_for_sqlite {
	my ($self, $table) = @_; # warn $table;

	my $dbh = $self->dbix;

	my $t = $dbh->query("PRAGMA table_info($table)")->hashes;
	my %meta = map { $_->{name} => $_ } @$t; # warn Dumper \%meta;
	return \%meta;
}

1;