Commit 37b96ac9 authored by Emmanuel Quevillon's avatar Emmanuel Quevillon

Merge branch 'develop' of https://github.com/kjolley/BIGSdb into develop

parents 47ee62d3 c3f954e4
Detailed installation instructions can be found at
http://bigsdb.readthedocs.org/.
http://bigsdb.readthedocs.io/.
......@@ -19,4 +19,4 @@ schemes so that types can be defined by combinations of allelic profiles, a
concept analagous to MLST.
The latest version of the BIGSdb documentation can be found at
http://bigsdb.readthedocs.org.
http://bigsdb.readthedocs.io.
Important notes about upgrading
-------------------------------
===============================
Version 1.1: Offline job manager - set up new user account and cron job.
Version 1.2: Change of isolate database structure. New package 'exonerate'
required.
......@@ -18,11 +17,13 @@ Version 1.11: Change of authentication database structure.
New Perl modules: Net::Oauth and Crypt::Eksblowfish::Bcrypt
required.
Version 1.12: Change of authentication and seqdef database structures.
Version 1.13: Change of seqdef and isolate database structures.
Version 1.14: Change of seqdef and isolate database structures.
Details can be found below.
More details about the upgrade process can be found at
http://bigsdb.readthedocs.org/en/latest/installation.html#upgrading-bigsdb.
http://bigsdb.readthedocs.io/en/latest/installation.html#upgrading-bigsdb.
Version 1.1
-----------
......@@ -273,3 +274,50 @@ The authentication database has also been modified to more flexibly support
client software permissions when accessing authenticated resources via the
RESTful API. Please run auth_v1.12.sql against your authentication database
(bigsdb_auth by default).
Version 1.13
------------
There are changes to the sequence definition database structure to support
profile retirement. There is also a new locus_stats table and additional fields
added to the sequences and allele_submission_sequences tables in preparation
for future functionality. Please run the seqdefdb_v1.13.sql script, found in
the sql/upgrade directory, against your seqdef database.
The isolate database has also been modified to support future functionality.
Please run isolatedb_v1.13.sql against your isolate databases.
Version 1.14
------------
There are large-scale changes to both the sequence definition and isolate
database structures to support cgMLST schemes with primary key indexing. The
previous method of caching scheme profiles did not support schemes with a ST
value and more than ~1600 loci due to PostgreSQL column limits. This did not
apply to schemes that were simply a collection of loci. Even before this limit
was reached, such large schemes would suffer performance penalties. The new
structure has no such limits.
Classification groups for cgMLST schemes are also introduced with this version.
This has necessitated a number of new tables in the database schemas.
Please run the seqdefdb_v1.14.sql against sequence definition databases and
isolatedb_v1.14.sql against isolate databases. These can be found in the
sql/upgrade directory.
Any scheme views set up in the sequence definition database named 'scheme_1'
etc. can be dropped as these are no longer used. To do this log in to the
database using psql, and type 'DROP VIEW scheme_1;'. Do this for each of the
scheme views.
If you are planning to use cgMLST schemes, you should ensure that your database
configuration has a temp_buffers setting of at least 64MB. This can be done by
editing bigsdb.conf and setting:
temp_buffers=64
Alternatively, this can be set globally in the postgresql.conf file (probably
/etc/postgresql/9.x/main/postgresql.conf) with the following line:
SET temp_buffers=64MB
Without this, the database engine is likely to run out of memory during cache
renewal.
......@@ -21,7 +21,7 @@
package BIGSdb::main;
use strict;
use warnings;
use version; our $VERSION = qv('v1.12.2');
use version; our $VERSION = qv('v1.14.1');
use 5.010;
###########Local configuration################################
......
......@@ -57,7 +57,14 @@ disable_updates=no
disable_update_message=
#URL root to web-accessible documentation.
doclink=http://bigsdb.readthedocs.org/en/latest
doclink=http://bigsdb.readthedocs.io/en/latest
#Maximum file upload size (MB)
max_upload_size=32
#Set PostgreSQL temporary buffers (MB) - likely to be needed if using cgMLST
#schemes. Alternatively this can be set globally in postgresql.conf.
temp_buffers=64
###REST INTERFACE###########
......
......@@ -13,6 +13,8 @@ log4perl.logger.BIGSdb.Locus=WARN, A1
log4perl.logger.BIGSdb.Scheme=WARN, A1
log4perl.logger.BIGSdb.Page=WARN, A1
log4perl.logger.BIGSdb.Script=WARN, A1
log4perl.logger.BIGSdb.Scan=WARN, A1
log4perl.logger.BIGSdb.Submissions=WARN, A1
log4perl.appender.A1=Log::Dispatch::File
log4perl.appender.A1.filename=/var/log/bigsdb_scripts.log
......
......@@ -16,7 +16,7 @@ Breakdown: <a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance&amp;page=plugin&amp;n
<a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance&amp;page=plugin&amp;name=PublicationBreakdown">Publications</a><br />
Links:
<a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance">Contents</a> |
<a href="http://bigsdb.readthedocs.org/">User guide</a> |
<a href="http://bigsdb.readthedocs.io/">User guide</a> |
<a href="$webroot/$indexpage">Home</a> |
<a href="/cgi-bin/bigsdb/bigscurate.pl?db=$instance">Curate</a>
</td>
......
......@@ -16,7 +16,7 @@ Breakdown: <a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance&amp;page=plugin&amp;n
<a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance&amp;page=plugin&amp;name=PublicationBreakdown">Publications</a><br />
Links:
<a href="/cgi-bin/bigsdb/bigsdb.pl?db=$instance">Contents</a> |
<a href="http://bigsdb.readthedocs.org/">User guide</a> |
<a href="http://bigsdb.readthedocs.io/">User guide</a> |
<a href="$webroot/$indexpage">Home</a> |
<a href="/cgi-bin/bigsdb/bigscurate.pl?db=$instance">Curate</a>
</td>
......
#Written by Keith Jolley
#Copyright (c) 2010-2015, University of Oxford
#Copyright (c) 2010-2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
......@@ -89,7 +89,7 @@ sub print_content {
say q(<dt>description</dt><dd>This is an arbitrary allele. When included )
. q(in a profile it means that this locus is ignored.</dd>);
} else {
say qq(<dt>sequences</dt><dd style="text-align:left" class="seq">$seq</dd>)
say qq(<dt>sequence</dt><dd style="text-align:left" class="seq">$seq</dd>)
. qq(<dt>length</dt><dd>$length</dd>)
. qq(<dt>status</dt><dd>$seq_ref->{'status'}</dd>)
. qq(<dt>date entered</dt><dd>$seq_ref->{'date_entered'}</dd>)
......
#Written by Keith Jolley
#(c) 2010-2015, University of Oxford
#(c) 2010-2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
......@@ -27,8 +27,8 @@ use BIGSdb::AuthorizeClientPage;
use BIGSdb::BatchProfileQueryPage;
use BIGSdb::BIGSException;
use BIGSdb::ChangePasswordPage;
use BIGSdb::ClassificationScheme;
use BIGSdb::CombinationQueryPage;
use BIGSdb::Constants qw(:limits);
use BIGSdb::CurateSubmissionExcelPage;
use BIGSdb::CustomizePage;
use BIGSdb::Dataconnector;
......@@ -79,9 +79,6 @@ sub new {
my $self = {};
$self->{'system'} = {};
$self->{'config'} = {};
$CGI::POST_MAX = MAX_UPLOAD_SIZE;
$CGI::DISABLE_UPLOADS = 0;
$self->{'cgi'} = CGI->new;
$self->{'instance'} = undef;
$self->{'xmlHandler'} = undef;
$self->{'page'} = undef;
......@@ -98,6 +95,10 @@ sub new {
$self->{'lib_dir'} = $lib_dir;
$self->{'dbase_config_dir'} = $dbase_config_dir;
bless( $self, $class );
$self->read_config_file($config_dir);
$CGI::POST_MAX = $self->{'config'}->{'max_upload_size'};
$CGI::DISABLE_UPLOADS = 0;
$self->{'cgi'} = CGI->new;
$self->_initiate( $config_dir, $dbase_config_dir );
$self->{'dataConnector'}->initiate( $self->{'system'}, $self->{'config'} );
$self->{'pages_needing_authentication'} = { map { $_ => 1 } PAGES_NEEDING_AUTHENTICATION };
......@@ -133,7 +134,6 @@ sub _initiate {
my ( $self, $config_dir, $dbase_config_dir ) = @_;
my $q = $self->{'cgi'};
Log::Log4perl::MDC->put( 'ip', $q->remote_host );
$self->read_config_file($config_dir);
$self->read_host_mapping_file($config_dir);
my $logger = get_logger('BIGSdb.Application_Initiate');
my $content_length = defined $ENV{'CONTENT_LENGTH'} ? $ENV{'CONTENT_LENGTH'} : 0;
......@@ -299,32 +299,52 @@ sub read_config_file {
my $logger = get_logger('BIGSdb.Application_Initiate');
my $config = Config::Tiny->new();
$config = Config::Tiny->read("$config_dir/bigsdb.conf");
foreach (
foreach my $param (
qw ( prefs_db auth_db jobs_db rest_db max_load emboss_path tmp_dir secure_tmp_dir submission_dir
blast+_path blast_threads muscle_path max_muscle_mb mafft_path mafft_threads mogrify_path ipcress_path
splitstree_path reference refdb ref_db chartdirector disable_updates disable_update_message intranet
debug results_deleted_days cache_days doclink rest_behind_proxy bcrypt_cost curate_script query_script
submissions_deleted_days smtp_server stylesheet domain)
submissions_deleted_days smtp_server stylesheet domain max_upload_size temp_buffers)
)
{
$self->{'config'}->{$_} = $config->{_}->{$_};
$self->{'config'}->{$param} = $config->{_}->{$param};
}
#Check integer values
foreach my $param (
qw(max_load blast_threads bcrypt_cost mafft_threads results_deleted_days cache_days submissions_deleted_days) )
{
if ( defined $self->{'config'}->{$param} && !BIGSdb::Utils::is_int( $self->{'config'}->{$param} ) ) {
$logger->error("Parameter $param in bigsdb.conf should be an integer - default value used.");
undef $self->{'config'}->{$param};
}
}
#Check float values
foreach my $param (qw(max_upload_size max_muscle_mb)) {
if ( defined $self->{'config'}->{$param} && !BIGSdb::Utils::is_float( $self->{'config'}->{$param} ) ) {
$logger->error("Parameter $param in bigsdb.conf should be a number - default value used.");
undef $self->{'config'}->{$param};
}
}
$self->{'config'}->{'intranet'} ||= 'no';
$self->{'config'}->{'cache_days'} //= 7;
if ( $self->{'config'}->{'chartdirector'} ) {
eval 'use perlchartdir'; ## no critic (ProhibitStringyEval)
eval 'use perlchartdir'; ## no critic (ProhibitStringyEval)
if ($@) {
$logger->error(q(Chartdirector not installed! - Either install or set 'chartdirector=0' in bigsdb.conf));
$self->{'config'}->{'chartdirector'} = 0;
} else {
eval 'use BIGSdb::Charts'; ## no critic (ProhibitStringyEval)
eval 'use BIGSdb::Charts'; ## no critic (ProhibitStringyEval)
if ($@) {
$logger->error('Charts.pm not installed!');
}
}
}
$self->{'config'}->{'aligner'} = 1 if $self->{'config'}->{'muscle_path'} || $self->{'config'}->{'mafft_path'};
$self->{'config'}->{'doclink'} //= 'http://bigsdb.readthedocs.org/en/latest';
$self->{'config'}->{'doclink'} //= 'http://bigsdb.readthedocs.io/en/latest';
$self->{'config'}->{'max_upload_size'} //= 32;
$self->{'config'}->{'max_upload_size'} *= 1024 * 1024;
return;
}
......
#Written by Keith Jolley
#Copyright (c) 2010-2015, University of Oxford
#Copyright (c) 2010-2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
......@@ -33,7 +33,7 @@ sub get_title {
sub initiate {
my ($self) = @_;
if ( $self->{'cgi'}->param('function') && $self->{'cgi'}->param('function') eq 'examples' ) {
if ( $self->{'cgi'}->param('function') ) {
$self->{'type'} = 'text';
} else {
$self->{'jQuery'} = 1;
......@@ -44,9 +44,12 @@ sub initiate {
sub print_content {
my ($self) = @_;
my $q = $self->{'cgi'};
if ( $q->param('function') && $q->param('function') eq 'examples' ) {
if ( ( $q->param('function') // q() ) eq 'examples' ) {
$self->_print_examples;
return;
} elsif ( ( $q->param('function') // q() ) eq 'col_order' ) {
$self->_print_col_order;
return;
}
my $scheme_id = $q->param('scheme_id');
my $desc = $self->get_db_description;
......@@ -63,27 +66,29 @@ sub print_content {
$scheme_id = $q->param('scheme_id'); #Will be set by scheme section method
}
my $loci = $self->{'datastore'}->get_scheme_loci($scheme_id);
my @cleaned_loci;
push @cleaned_loci, $self->clean_locus($_) foreach @$loci;
if ( $q->param('profiles') ) {
my $profiles = $q->param('profiles');
my @rows = split /\n/x, $profiles;
my @cleaned_loci;
push @cleaned_loci, $self->clean_locus($_) foreach @$loci;
local $" = q(</th><th>);
say q(<div class="box" id="resultstable">);
say q(<div class="scrollable">);
say qq(<table class="resultstable"><tr><th>Isolate</th><th>@cleaned_loci</th>);
my $scheme_fields = $self->{'datastore'}->get_scheme_fields($scheme_id);
foreach my $field (@$scheme_fields) {
my $cleaned = $field;
$cleaned =~ tr/_/ /;
print qq(<th>$cleaned</th>);
}
local $" = ',';
my $scheme_view =
$self->{'datastore'}->materialized_view_exists($scheme_id) ? "mv_scheme_$scheme_id" : "scheme_$scheme_id";
my $qry = "SELECT @$scheme_fields FROM $scheme_view WHERE ";
my @cleaned_loci_db = @$loci;
$_ =~ s/'/_PRIME_/gx foreach @cleaned_loci_db;
my $scheme_warehouse = "mv_scheme_$scheme_id";
my $qry = "SELECT @$scheme_fields FROM $scheme_warehouse WHERE ";
my @cleaned_loci_db;
foreach my $locus (@$loci) {
push @cleaned_loci_db, $self->{'datastore'}->get_scheme_warehouse_locus_name( $scheme_id, $locus );
}
my $set_id = $self->get_set_id;
my $scheme_info = $self->{'datastore'}->get_scheme_info( $scheme_id, { set_id => $set_id } );
local $" = $scheme_info->{'allow_missing_loci'} ? q[ IN (?, 'N')) AND (] : q[=?) AND (];
......@@ -145,7 +150,9 @@ sub print_content {
say q[<p>Enter allelic profiles below in tab-delimited text format using copy and paste ]
. q[(for example directly from a spreadsheet). Columns can be separated by any amount of whitespace. ]
. q[The first column should be an isolate identifier and the remaining ]
. qq[columns should comprise the allele numbers (order: @cleaned_loci). Click here for ]
. qq[columns should comprise the allele numbers (<a href="$self->{'system'}->{'script_name'}?]
. qq[db=$self->{'instance'}&amp;page=batchProfiles&amp;function=col_order&amp;scheme_id=$scheme_id">]
. q[show column order</a>). Click here for ]
. qq[<a href="$self->{'system'}->{'script_name'}?db=$self->{'instance'}&amp;page=batchProfiles&amp;]
. qq[function=examples&amp;scheme_id=$scheme_id">example data</a>. Non-numerical characters will be ]
. q[stripped out of the query.</p>];
......@@ -158,10 +165,9 @@ sub print_content {
return;
}
#Generate example data file for batch profile query
#Get up to 15 random profiles from the database
sub _print_examples {
#Generate example data file for batch profile query
#Get up to 15 random profiles from the database
my ($self) = @_;
my $q = $self->{'cgi'};
my $scheme_id = $q->param('scheme_id');
......@@ -177,21 +183,44 @@ sub _print_examples {
print "Invalid scheme selected.\n";
return;
}
my $loci = $self->{'datastore'}->get_scheme_loci($scheme_id);
my @cleaned_loci = @$loci;
$_ =~ s/'/_PRIME_/gx foreach @cleaned_loci;
local $" = ',';
my $scheme_view =
$self->{'datastore'}->materialized_view_exists($scheme_id) ? "mv_scheme_$scheme_id" : "scheme_$scheme_id";
my $data = $self->{'datastore'}->run_query( "SELECT @cleaned_loci FROM $scheme_view ORDER BY random() LIMIT 15",
undef, { fetch => 'all_arrayref' } );
my $loci = $self->{'datastore'}->get_scheme_loci($scheme_id);
my $scheme_warehouse = "mv_scheme_$scheme_id";
my $data = $self->{'datastore'}->run_query( "SELECT profile FROM $scheme_warehouse ORDER BY random() LIMIT 15",
undef, { fetch => 'col_arrayref' } );
if ( !@$data ) {
say q(No profiles have yet been defined for this scheme.);
return;
}
my $i = 1;
my $indices = $self->{'datastore'}->get_scheme_locus_indices($scheme_id);
local $" = "\t";
my $i = 1;
foreach my $profile (@$data) {
say qq(isolate_$i\t@$profile);
my @alleles;
foreach my $locus (@$loci) {
push @alleles, $profile->[ $indices->{$locus} ];
}
say qq(isolate_$i\t@alleles);
$i++;
}
return;
}
sub _print_col_order {
my ($self) = @_;
my $q = $self->{'cgi'};
my $scheme_id = $q->param('scheme_id');
if ( !BIGSdb::Utils::is_int($scheme_id) ) {
$scheme_id = -1;
}
if ( $self->{'system'}->{'dbtype'} ne 'sequences' ) {
say q(This function is only available for sequence definition databases.);
return;
}
my @cleaned_loci;
my $loci = $self->{'datastore'}->get_scheme_loci($scheme_id);
push @cleaned_loci, $self->clean_locus( $_, { text_output => 1 } ) foreach @$loci;
local $" = qq(\t);
say qq(id\t@cleaned_loci);
return;
}
1;
#Written by Keith Jolley
#Copyright (c) 2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
#
#BIGSdb is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#BIGSdb is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with BIGSdb. If not, see <http://www.gnu.org/licenses/>.
package BIGSdb::ClassificationScheme;
use strict;
use warnings;
use 5.010;
use Log::Log4perl qw(get_logger);
my $logger = get_logger('BIGSdb.Scheme');
sub new { ## no critic (RequireArgUnpacking)
my $class = shift;
my $self = {@_};
$self->{'sql'} = {};
bless( $self, $class );
$logger->info("Classification scheme#$self->{'id'} ($self->{'name'}) set up.");
return $self;
}
sub get_db {
my ($self) = @_;
return $self->{'db'} if $self->{'db'};
return;
}
1;
\ No newline at end of file
#Written by Keith Jolley
#Copyright (c) 2010-2015, University of Oxford
#Copyright (c) 2010-2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
......@@ -60,7 +60,8 @@ sub print_content {
if $scheme_id
&& $self->is_scheme_invalid( $scheme_id, { with_pk => $with_pk, all_loci => $all_loci } );
$self->print_scheme_section( { with_pk => $with_pk, all_loci => $all_loci } );
$scheme_id = $q->param('scheme_id'); #Will be set by scheme section method
$scheme_id = $q->param('scheme_id'); #Will be set by scheme section method
$scheme_id = 0 if !BIGSdb::Utils::is_int($scheme_id);
$self->_print_query_interface($scheme_id);
}
if ( defined $q->param('query_file')
......@@ -96,20 +97,12 @@ sub _autofill {
push @errors, 'Error retrieving information from remote database - check configuration.';
};
} else {
my @cleaned_loci = @$loci;
foreach my $locus (@cleaned_loci) {
$locus =~ s/'/_PRIME_/gx;
}
local $" = ',';
my $scheme_view =
$self->{'datastore'}->materialized_view_exists($scheme_id)
? "mv_scheme_$scheme_id"
: "scheme_$scheme_id";
my $qry = "SELECT @cleaned_loci FROM $scheme_view WHERE $primary_key=?";
my $loci_values = $self->{'datastore'}->run_query( $qry, $pk_value, { fetch => 'row_hashref' } );
my $scheme_warehouse = "mv_scheme_$scheme_id";
my $qry = "SELECT profile FROM $scheme_warehouse WHERE $primary_key=?";
my $profile = $self->{'datastore'}->run_query( $qry, $pk_value );
my $locus_indices = $self->{'datastore'}->get_scheme_locus_indices($scheme_id);
foreach my $locus (@$loci) {
( my $cleaned = $locus ) =~ s/'/_PRIME_/gx;
$q->param( "l_$locus", $loci_values->{ lc($cleaned) } );
$q->param( "l_$locus", $profile->[ $locus_indices->{$locus} ] );
}
}
}
......@@ -194,7 +187,12 @@ sub _print_query_interface {
say qq(<tr>$header_row</tr>);
say qq(<tr>$form_row</tr>);
say q(</table></fieldset>);
if ($primary_key) {
if (
$primary_key
&& ( ( $self->{'system'}->{'dbtype'} eq 'isolates' && $scheme_info->{'dbase_table'} )
|| $self->{'system'}->{'dbtype'} eq 'sequences' )
)
{
my $remote = $self->{'system'}->{'dbtype'} eq 'isolates' ? ' by searching remote database' : '';
say qq(<fieldset id="autofill_fieldset" style="float:left"><legend>Autofill profile$remote</legend><ul>);
my $first = 1;
......@@ -263,22 +261,12 @@ sub _print_query_interface {
return;
}
sub _get_scheme_view {
my ( $self, $scheme_id ) = @_;
if ( $self->{'system'}->{'dbtype'} eq 'sequences' ) {
return $self->{'datastore'}->materialized_view_exists($scheme_id)
? "mv_scheme_$scheme_id"
: "scheme_$scheme_id";
}
return;
}
sub _generate_query {
my ( $self, $scheme_id ) = @_;
my $scheme_info = $self->{'datastore'}->get_scheme_info( $scheme_id, { get_pk => 1 } );
my $scheme_view = $self->_get_scheme_view($scheme_id);
my $q = $self->{'cgi'};
my @params = $q->param;
my $scheme_info = $self->{'datastore'}->get_scheme_info( $scheme_id, { get_pk => 1 } );
my $scheme_warehouse = "mv_scheme_$scheme_id";
my $q = $self->{'cgi'};
my @params = $q->param;
my @errors;
my $msg;
my $qry;
......@@ -342,7 +330,7 @@ sub _generate_query {
if (@lqry) {
local $" = ' OR ';
my $required_matches = $q->param('matches_list');
$required_matches = scalar @lqry if $required_matches == @loci;
$required_matches = @lqry if $required_matches == @loci;
my $lqry;
if ( $self->{'system'}->{'dbtype'} eq 'isolates' ) {
$lqry = "(SELECT DISTINCT($view.id) FROM $view LEFT JOIN allele_designations ON "
......@@ -352,7 +340,7 @@ sub _generate_query {
'(SELECT DISTINCT(profiles.profile_id) FROM profiles LEFT JOIN profile_members ON '
. 'profiles.profile_id=profile_members.profile_id AND profiles.scheme_id=profile_members.scheme_id '
. "AND profile_members.scheme_id=$scheme_id WHERE "
. "$scheme_view.$scheme_info->{'primary_key'}=profiles.profile_id AND (@lqry)";
. "$scheme_warehouse.$scheme_info->{'primary_key'}=profiles.profile_id AND (@lqry)";
}
if ( $required_matches == 0 ) { #Find out the greatest number of matches
my $match = $self->_find_best_match_count( $scheme_id, \@lqry );
......@@ -368,7 +356,7 @@ sub _generate_query {
$qry =
$self->{'system'}->{'dbtype'} eq 'isolates'
? "SELECT * FROM $view WHERE $view.id IN $lqry"
: "SELECT * FROM $scheme_view WHERE EXISTS $lqry";
: "SELECT * FROM $scheme_warehouse WHERE EXISTS $lqry";
}
$self->_modify_qry_by_filters( \$qry );
$self->_add_query_ordering( \$qry, $scheme_id );
......
#Written by Keith Jolley
#Copyright (c) 2010-2015, University of Oxford
#Copyright (c) 2010-2016, University of Oxford
#E-mail: keith.jolley@zoo.ox.ac.uk
#
#This file is part of Bacterial Isolate Genome Sequence Database (BIGSdb).
......@@ -38,6 +38,7 @@ sub print_content {
if ( $self->{'system'}->{'dbtype'} eq 'isolates' ) {
$self->_check_locus_databases;
$self->_check_scheme_databases;
$self->_check_classification_scheme_databases;
} else {
$self->_check_client_databases;
}
......@@ -85,32 +86,42 @@ sub _check_helpers {
sub _check_locus_databases {
my ($self) = @_;
my $q = $self->{'cgi'};
say q(<div class="box resultstable">);
say q(<h2>Locus databases</h2>);
my $with_probs =
$q->param('show_probs_only')
? q[ (only showing loci with potential problems - ]
. qq[<a href="$self->{'system'}->{'script_name'}?db=$self->{'instance'}&amp;page=configCheck">]
. q[show all loci</a>)]
: q[];
say qq(<h2>Locus databases$with_probs</h2>);
my $set_id = $self->get_set_id;
my $set_clause =
$set_id
? 'AND (id IN (SELECT locus FROM scheme_members WHERE scheme_id IN (SELECT scheme_id FROM set_schemes '
. 'WHERE set_id=$set_id)) OR id IN (SELECT locus FROM set_loci WHERE set_id=$set_id))'
. "WHERE set_id=$set_id)) OR id IN (SELECT locus FROM set_loci WHERE set_id=$set_id))"
: '';
my $loci =
$self->{'datastore'}->run_query( "SELECT id FROM loci WHERE dbase_name IS NOT null $set_clause ORDER BY id",
undef, { fetch => 'col_arrayref' } );
my $td = 1;
if (@$loci) {
say q(<div class="scrollable"><table class="resultstable"><tr><th>Locus</th><th>Database</th>)
. q(<th>Host</th><th>Port</th><th>Table</th><th>Primary id field</th><th>Secondary id field</th>)
. q(<th>Secondary id field value</th><th>Sequence field</th><th>Database accessible</th>)
. q(<th>Sequence query</th><th>Sequences assigned</th></tr>);
foreach my $locus (@$loci) {
LOCUS: foreach my $locus (@$loci) {
if ( $ENV{'MOD_PERL'} ) {
$self->{'mod_perl_request'}->rflush;
return if $self->{'mod_perl_request'}->connection->aborted;
}