package NGS::DB; use Moo; use Path::Tiny; use Data::Printer; use FindBin qw($RealBin); # warn $RealBin; use NGS::MooX::Types qw(String); use Time::HiRes qw(gettimeofday tv_interval); use SQL::Abstract; use SQL::Abstract::Plugin::InsertMulti; use lib '/home/raj/perl-lib'; use Local::DB; has session_id => ( is => 'rw', isa => String ); # optional, eg data for download has ref_libs => ( is => 'lazy' ); # SQLite db has vep_db => ( is => 'lazy' ); # MySQL ngs db sub known_locations { my $self = shift; my $dbix = $self->ref_libs; my $query = $dbix->select('locations', ['position', 'action']); my %h; while ( $query->into( my ($position, $action) ) ) { $h{$action}{$position} = 1; } # p %h; return \%h; } sub transcripts { my $self = shift; my $dbix = $self->ref_libs; my $map = $dbix->select('transcripts', ['gene', 'feature'])->map; return $map; } sub ref_table { my $self = shift; my $dbix = $self->ref_libs; my $ref_tbl = $dbix->select('ref_seq', '*')->map_hashes('gene'); # p $ref_tbl; return $ref_tbl; } sub update_vep_table { my ($self, $tbl, $data) = @_; # str, AoH my $dbix = $self->vep_db; # p $data; # delete any already there: $dbix->delete($tbl, { id => $self->session_id }); # warn $self->session_id; my $cols = $self->get_cols($tbl); my $vars = join ',', grep { $_ ne 'timestamp' } @$cols; my $t0 = [gettimeofday]; # set t0 =begin # usual dbix methods way too slow (eg for 1100 vep input): $dbix->insert($tbl, $_) for @$data; # 35 secs my $sql = "insert into $tbl($vars) values (??)"; $dbix->query($sql, @{$_}{@$cols}) for @$data; 50 secs =cut my $sql = SQL::Abstract->new; # allows AoA @all_data insert - much faster my @all_data = map { [ @{$_}{@$cols} ] } @$data; # p @foo; my ($stmt, @bind) = $sql->insert_multi($tbl, $cols, \@all_data); $dbix->query($stmt, @bind); # much faster than a looping query() or insert() my $runtime = tv_interval $t0, [gettimeofday]; # p $runtime; # about 1100/sec } sub get_vep_data { my $self = shift; my $dbix = $self->vep_db; my $session_id = $self->session_id; my %h; for my $tbl ( qw/vep_data non_cds/ ) { my $all_cols = $self->get_cols($tbl); # p $all_cols; my @cols = grep { $_ !~ m!\A(timestamp|id)\Z! } @$all_cols; # p @cols; $h{$tbl} = $dbix->select($tbl, \@cols, { id => $session_id})->arrays; } return \%h; } sub get_cols { my ($self, $tbl) = @_; my $dbix = $self->vep_db; no warnings 'uninitialized'; # non-timestamp col has no default val my @cols = map $_->{field}, grep { $_->{default} !~ /timestamp/i } $dbix->query('show columns from '.$tbl)->hashes; return \@cols; } #------------------------------------------------------------------------------- sub _build_ref_libs { # SQLite db my $db = path($RealBin, '..', 'ngs.sqlite')->realpath; # warn 'DB:'. $db; my $dsn = "dbi:SQLite:dbname=$db"; my $o = Local::DB->dbix({ dsn => $dsn }); # p $o; return $o; } sub _build_vep_db { Local::DB->dbix('ngs') } # MySQL 1;