<commit_before>package MGRAST::Analysis;

use strict;
use warnings;
no warnings('once');

use List::Util qw(max min sum first);
use List::MoreUtils qw(natatime);
use Conf;
use DBI;
use Data::Dumper;
use Babel::lib::Babel;

use Cache::Memcached;
use File::Temp qw/ tempfile tempdir /;

1;

sub new {
  my ($class, $job_dbh, $dbh) = @_;

  # get ach object
  my $ach = new Babel::lib::Babel;
  
  # get memcache object
  my $memd = new Cache::Memcached {'servers' => [$Conf::web_memcache || "kursk-2.mcs.anl.gov:11211"], 'debug' => 0, 'compress_threshold' => 10_000};
  
  # connect to database

  unless ($dbh){
    eval {
      my $dbms     = $Conf::mgrast_dbms;
      my $host     = "kharkov-1.igsb.anl.gov"; ### hardocded !!! $Conf::mgrast_dbhost;
      my $database = $Conf::mgrast_db;
      my $user     = $Conf::mgrast_dbuser;
      my $password = $Conf::mgrast_dbpass;
      
      $dbh = DBI->connect("DBI:$dbms:dbname=$database;host=$host", $user, $password, 
			  { RaiseError => 1, AutoCommit => 0, PrintError => 0 }) ||
			    die "database connect error.";
    };
    if ($@) {
      warn "Unable to connect to metagenomics database: $@\n";
      return undef;
    }

  }
  unless ($job_dbh && ref($job_dbh)) {
    warn "Unable to connect to job_cache database\n";
    return undef;
  }
  $dbh->{pg_expand_array} = 1;

  # set sources
  my $srcs  = $dbh->selectall_hashref("SELECT * FROM sources", "name");
  my %idsrc = map { $srcs->{$_}{_id}, $_ } keys %$srcs;
  my %srcid = map { $_, $srcs->{$_}{_id} } keys %$srcs;

  # create object
  my $self = { dbh     => $dbh,     # job data db_handle
	           ach     => $ach,     # ach/babel object
	           jcache  => $job_dbh, # job cache db_handle
	           memd    => $memd,    # memcached handle
	           jobs    => [],       # array: job_id	           
	           job_map => {},       # hash: mg_id => job_id
	           mg_map  => {},       # hash: job_id => mg_id
	           sources => $srcs,    # hash: source_name => { col => value }
	           id_src  => \%idsrc,  # hash: source_id => source_name
   	           src_id  => \%srcid,  # hash: source_name => source_id
	           expire  => $Conf::web_memcache_expire || 172800, # use config or 48 hours
	           version => $Conf::m5nr_annotation_version || 1,
	           jtbl    => { md5          => 'job_md5s',
	                        ontology     => 'job_ontologies',
	                        function     => 'job_functions',
	                        organism     => 'job_organisms',
	                        lca          => 'job_lcas' },
	           atbl    => { md5          => 'md5s',
	                        ontology     => 'ontologies',
	                        function     => 'functions',
	                        organism     => 'organisms_ncbi' }
	         };
  bless $self, $class;
  return $self;
}

sub DESTROY {
   my ($self) = @_;
   if ($self->{dbh})    { $self->{dbh}->disconnect; }
   if ($self->{ach})    { $self->{ach}->DESTROY; }
   if ($self->{jcache}) { $self->{jcache}->disconnect; }
}

sub _dbh {
  my ($self) = @_;
  return $self->{dbh};
}
sub ach {
  my ($self) = @_;
  return $self->{ach};
}
sub _jcache {
  my ($self) = @_;
  return $self->{jcache};
}
sub _memd {
  my ($self) = @_;
  return $self->{memd};
}
sub _jobs {
  my ($self) = @_;
  return $self->{jobs};
}
sub _qjobs {
  my ($self) = @_;
  return "job IN (".join(',', @{$self->{jobs}}).")";
}
sub _job_map {
  my ($self) = @_;
  return $self->{job_map};
}
sub _mg_map {
  my ($self) = @_;
  return $self->{mg_map};
}
sub _id_src {
  my ($self) = @_;
  return $self->{id_src};
}
sub _src_id {
  my ($self) = @_;
  return $self->{src_id};
}
sub _sources {
  my ($self) = @_;
  return $self->{sources};
}
sub _expire {
  my ($self) = @_;
  return $self->{expire};
}
sub _version {
  my ($self) = @_;
  return $self->{version};
}
sub _qver {
  my ($self) = @_;
  return "version = ".$self->{version};
}
sub _jtbl {
  my ($self) = @_;
  return $self->{jtbl};
}
sub _atbl {
  my ($self) = @_;
  return $self->{atbl};
}
sub _has_job {
  my ($self, $mgid) = @_;
  return exists($self->_job_map->{$mgid}) ? 1 : 0;
}

# add values to $self->{jobs} based on metagenome_id list
sub add_jobs {
  my ($self, $mgids) = @_;
  if ($mgids && scalar(@$mgids)) {
    my @new_mg  = grep { ! $self->_has_job($_) } @$mgids;
    my $new_map = $self->_get_jobid_map(\@new_mg);
    %{ $self->{job_map} } = ( %{$self->{job_map}}, %$new_map );
    $self->_set_data();
  }
}

# set values for $self->{jobs} and $self->{jtbl} based on metagenome_id list
sub set_jobs {
  my ($self, $mgids, $jids) = @_;
  if (defined($jids)) {
    $self->{job_map} = $self->_get_jobid_map($mgids, 1);
  } else {
    $self->{job_map} = $self->_get_jobid_map($mgids);
  }
  $self->_set_data();
}

# populate obj with all public jobs
sub set_public_jobs {
  my ($self) = @_;
  my $mgids = $self->_jcache->selectcol_arrayref("SELECT metagenome_id FROM Job WHERE public = 1 AND viewable = 1");
  if ($mgids && (@$mgids > 0)) {
    $self->set_jobs($mgids);
  }
}

sub _set_data {
    my ($self) = @_;
    my %rev = reverse %{$self->{job_map}};
    $self->{mg_map} = \%rev;
    $self->{jobs} = values %{$self->{job_map}};
}

sub _get_jobid_map {
  my ($self, $mgids, $jids) = @_;
  unless ($mgids && scalar(@$mgids)) {
    return {};
  }
  my $hash = {};
  my $list = join(",", map {"'$_'"} @$mgids);<commit_msg>analysis.pm: fixed bug with array derefrence<commit_after>package MGRAST::Analysis;

use strict;
use warnings;
no warnings('once');

use List::Util qw(max min sum first);
use List::MoreUtils qw(natatime);
use Conf;
use DBI;
use Data::Dumper;
use Babel::lib::Babel;

use Cache::Memcached;
use File::Temp qw/ tempfile tempdir /;

1;

sub new {
  my ($class, $job_dbh, $dbh) = @_;

  # get ach object
  my $ach = new Babel::lib::Babel;
  
  # get memcache object
  my $memd = new Cache::Memcached {'servers' => [$Conf::web_memcache || "kursk-2.mcs.anl.gov:11211"], 'debug' => 0, 'compress_threshold' => 10_000};
  
  # connect to database

  unless ($dbh){
    eval {
      my $dbms     = $Conf::mgrast_dbms;
      my $host     = "kharkov-1.igsb.anl.gov"; ### hardocded !!! $Conf::mgrast_dbhost;
      my $database = $Conf::mgrast_db;
      my $user     = $Conf::mgrast_dbuser;
      my $password = $Conf::mgrast_dbpass;
      
      $dbh = DBI->connect("DBI:$dbms:dbname=$database;host=$host", $user, $password, 
			  { RaiseError => 1, AutoCommit => 0, PrintError => 0 }) ||
			    die "database connect error.";
    };
    if ($@) {
      warn "Unable to connect to metagenomics database: $@\n";
      return undef;
    }

  }
  unless ($job_dbh && ref($job_dbh)) {
    warn "Unable to connect to job_cache database\n";
    return undef;
  }
  $dbh->{pg_expand_array} = 1;

  # set sources
  my $srcs  = $dbh->selectall_hashref("SELECT * FROM sources", "name");
  my %idsrc = map { $srcs->{$_}{_id}, $_ } keys %$srcs;
  my %srcid = map { $_, $srcs->{$_}{_id} } keys %$srcs;

  # create object
  my $self = { dbh     => $dbh,     # job data db_handle
	           ach     => $ach,     # ach/babel object
	           jcache  => $job_dbh, # job cache db_handle
	           memd    => $memd,    # memcached handle
	           jobs    => [],       # array: job_id	           
	           job_map => {},       # hash: mg_id => job_id
	           mg_map  => {},       # hash: job_id => mg_id
	           sources => $srcs,    # hash: source_name => { col => value }
	           id_src  => \%idsrc,  # hash: source_id => source_name
   	           src_id  => \%srcid,  # hash: source_name => source_id
	           expire  => $Conf::web_memcache_expire || 172800, # use config or 48 hours
	           version => $Conf::m5nr_annotation_version || 1,
	           jtbl    => { md5          => 'job_md5s',
	                        ontology     => 'job_ontologies',
	                        function     => 'job_functions',
	                        organism     => 'job_organisms',
	                        lca          => 'job_lcas' },
	           atbl    => { md5          => 'md5s',
	                        ontology     => 'ontologies',
	                        function     => 'functions',
	                        organism     => 'organisms_ncbi' }
	         };
  bless $self, $class;
  return $self;
}

sub DESTROY {
   my ($self) = @_;
   if ($self->{dbh})    { $self->{dbh}->disconnect; }
   if ($self->{ach})    { $self->{ach}->DESTROY; }
   if ($self->{jcache}) { $self->{jcache}->disconnect; }
}

sub _dbh {
  my ($self) = @_;
  return $self->{dbh};
}
sub ach {
  my ($self) = @_;
  return $self->{ach};
}
sub _jcache {
  my ($self) = @_;
  return $self->{jcache};
}
sub _memd {
  my ($self) = @_;
  return $self->{memd};
}
sub _jobs {
  my ($self) = @_;
  return $self->{jobs};
}
sub _qjobs {
  my ($self) = @_;
  return "job IN (".join(',', @{$self->{jobs}}).")";
}
sub _job_map {
  my ($self) = @_;
  return $self->{job_map};
}
sub _mg_map {
  my ($self) = @_;
  return $self->{mg_map};
}
sub _id_src {
  my ($self) = @_;
  return $self->{id_src};
}
sub _src_id {
  my ($self) = @_;
  return $self->{src_id};
}
sub _sources {
  my ($self) = @_;
  return $self->{sources};
}
sub _expire {
  my ($self) = @_;
  return $self->{expire};
}
sub _version {
  my ($self) = @_;
  return $self->{version};
}
sub _qver {
  my ($self) = @_;
  return "version = ".$self->{version};
}
sub _jtbl {
  my ($self) = @_;
  return $self->{jtbl};
}
sub _atbl {
  my ($self) = @_;
  return $self->{atbl};
}
sub _has_job {
  my ($self, $mgid) = @_;
  return exists($self->_job_map->{$mgid}) ? 1 : 0;
}

# add values to $self->{jobs} based on metagenome_id list
sub add_jobs {
  my ($self, $mgids) = @_;
  if ($mgids && scalar(@$mgids)) {
    my @new_mg  = grep { ! $self->_has_job($_) } @$mgids;
    my $new_map = $self->_get_jobid_map(\@new_mg);
    %{ $self->{job_map} } = ( %{$self->{job_map}}, %$new_map );
    $self->_set_data();
  }
}

# set values for $self->{jobs} and $self->{jtbl} based on metagenome_id list
sub set_jobs {
  my ($self, $mgids, $jids) = @_;
  if (defined($jids)) {
    $self->{job_map} = $self->_get_jobid_map($mgids, 1);
  } else {
    $self->{job_map} = $self->_get_jobid_map($mgids);
  }
  $self->_set_data();
}

# populate obj with all public jobs
sub set_public_jobs {
  my ($self) = @_;
  my $mgids = $self->_jcache->selectcol_arrayref("SELECT metagenome_id FROM Job WHERE public = 1 AND viewable = 1");
  if ($mgids && (@$mgids > 0)) {
    $self->set_jobs($mgids);
  }
}

sub _set_data {
    my ($self) = @_;
    my %rev = reverse %{$self->{job_map}};
    $self->{mg_map} = \%rev;
    @{$self->{jobs}} = values %{$self->{job_map}};
}

sub _get_jobid_map {
  my ($self, $mgids, $jids) = @_;
  unless ($mgids && scalar(@$mgids)) {
    return {};
  }
  my $hash = {};
  my $list = join(",", map {"'$_'"} @$mgids);
{'fraction_non_alphanumeric': 0.19183786785119378, 'fraction_numerical': 0.007033129742735517, 'mean_word_length': 2.421019309908199, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 179, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4771856', 'n_tokens_mistral': 4292, 'n_tokens_neox': 4119, 'n_words': 922}