Skip to content
Snippets Groups Projects
Commit 847ebd02 authored by Daniel Rios's avatar Daniel Rios
Browse files

moved query constructors to BaseAdaptor module

parent 032fb3d4
No related branches found
No related tags found
No related merge requests found
......@@ -93,7 +93,6 @@ use strict;
use Bio::EnsEMBL::Root;
use Bio::EnsEMBL::Utils::Exception qw(throw);
@ISA = qw(Bio::EnsEMBL::Root);
......@@ -210,4 +209,335 @@ sub _list_dbIDs {
return \@out;
}
# _straight_join
# Arg [1] : (optional) boolean $new_val
# Example : $self->_straight_join(1);
# $self->generic_fetch($constraint);
# $self->_straight_join(0);
# Description: PROTECTED Getter/Setter that turns on/off the use of
# a straight join in queries.
# Returntype : boolean
# Exceptions : none
# Caller : general
sub _straight_join {
my $self = shift;
if(@_) {
$self->{'_straight_join'} = shift;
}
return $self->{'_straight_join'};
}
=head2 generic_fetch
Arg [1] : (optional) string $constraint
An SQL query constraint (i.e. part of the WHERE clause)
Arg [2] : (optional) Bio::EnsEMBL::AssemblyMapper $mapper
A mapper object used to remap features
as they are retrieved from the database
Arg [3] : (optional) Bio::EnsEMBL::Slice $slice
A slice that features should be remapped to
Example : $fts = $a->generic_fetch('contig_id in (1234, 1235)', 'Swall');
Description: Performs a database fetch and returns feature objects in
contig coordinates.
Returntype : listref of Bio::EnsEMBL::SeqFeature in contig coordinates
Exceptions : none
Caller : BaseFeatureAdaptor, ProxyDnaAlignFeatureAdaptor::generic_fetch
=cut
sub generic_fetch {
my ($self, $constraint, $mapper, $slice) = @_;
my @tabs = $self->_tables;
my $columns = join(', ', $self->_columns());
my $db = $self->db();
#
# Construct a left join statement if one was defined, and remove the
# left-joined table from the table list
#
my @left_join_list = $self->_left_join();
my $left_join = '';
my @tables;
if(@left_join_list) {
my %left_join_hash = map { $_->[0] => $_->[1] } @left_join_list;
while(my $t = shift @tabs) {
if( exists $left_join_hash{ $t->[0] } ) {
my $condition = $left_join_hash{ $t->[0] };
my $syn = $t->[1];
$left_join .= "LEFT JOIN\n ".$t->[0]." $syn ON $condition ";
} else {
push @tables, $t;
}
}
} else {
@tables = @tabs;
}
my $straight_join = '';
if($self->_straight_join()) {
$straight_join = "STRAIGHT_JOIN";
}
#construct a nice table string like 'table1 t1, table2 t2'
my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
my $sql = "SELECT $straight_join $columns\n FROM $tablenames $left_join";
my $default_where = $self->_default_where_clause;
my $final_clause = $self->_final_clause;
#append a where clause if it was defined
if($constraint) {
$sql .= "\n WHERE $constraint ";
if($default_where) {
$sql .= " AND\n $default_where ";
}
} elsif($default_where) {
$sql .= "\n WHERE $default_where ";
}
#append additional clauses which may have been defined
$sql .= "\n$final_clause";
my $sth = $db->dbc->prepare($sql);
$sth->execute;
my $res = $self->_objs_from_sth($sth, $mapper, $slice);
return $res;
}
=head2 fetch_by_dbID
Arg [1] : int $id
The unique database identifier for the feature to be obtained
Example : $feat = $adaptor->fetch_by_dbID(1234));
$feat = $feat->transform('contig');
Description: Returns the feature created from the database defined by the
the id $id. The feature will be returned in its native
coordinate system. That is, the coordinate system in which it
is stored in the database. In order to convert it to a
particular coordinate system use the transfer() or transform()
method. If the feature is not found in the database then
undef is returned instead
Returntype : Bio::EnsEMBL::Feature or undef
Exceptions : thrown if $id arg is not provided
does not exist
Caller : general
=cut
sub fetch_by_dbID{
my ($self,$id) = @_;
throw("id argument is required") if(!defined $id);
#construct a constraint like 't1.table1_id = 123'
my @tabs = $self->_tables;
my ($name, $syn) = @{$tabs[0]};
my $constraint = "${syn}.${name}_id = $id";
#Should only be one
my ($feat) = @{$self->generic_fetch($constraint)};
return undef if(!$feat);
return $feat;
}
=head2 fetch_all_by_dbID_list
Arg [1] : listref of ints $id_list
The unique database identifiers for the features to be obtained
Example : @feats = @{$adaptor->fetch_by_dbID_list([1234, 2131, 982]))};
Description: Returns the features created from the database defined by the
the ids in contained in the id list $id_list. The features
will be returned in their native coordinate system. That is,
the coordinate system in which they are stored in the database.
In order to convert the features to a particular coordinate
system use the transfer() or transform() method. If none of the
features are found in the database a reference to an empty
list is returned.
Returntype : listref of Bio::EnsEMBL::Features
Exceptions : thrown if $id arg is not provided
does not exist
Caller : general
=cut
sub fetch_all_by_dbID_list {
my ($self,$id_list) = @_;
if(!defined($id_list) || ref($id_list) ne 'ARRAY') {
throw("id_list list reference argument is required");
}
return [] if(!@$id_list);
my @out;
#construct a constraint like 't1.table1_id = 123'
my @tabs = $self->_tables;
my ($name, $syn) = @{$tabs[0]};
# mysql is faster and we ensure that we do not exceed the max query size by
# splitting large queries into smaller queries of 200 ids
my $max_size = 200;
while(@$id_list) {
my @ids;
if(@$id_list > $max_size) {
@ids = splice(@$id_list, 0, $max_size);
} else {
@ids = splice(@$id_list, 0);
}
my $id_str;
if(@ids > 1) {
$id_str = " IN (" . join(',', @ids). ")";
} else {
$id_str = " = " . $ids[0];
}
my $constraint = "${syn}.${name}_id $id_str";
push @out, @{$self->generic_fetch($constraint)};
}
return \@out;
}
#_tables
#
# Args : none
# Example : $tablename = $self->_table_name()
# Description: ABSTRACT PROTECTED Subclasses are responsible for implementing
# this method. It should list of [tablename, alias] pairs.
# Additionally the primary table (with the dbID, analysis_id, and
# score) should be the first table in the list.
# e.g:
# ( ['repeat_feature', 'rf'],
# ['repeat_consensus', 'rc']);
# used to obtain features.
# Returntype : list of [tablename, alias] pairs
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
#
sub _tables {
my $self = shift;
throw("abstract method _tables not defined by implementing" .
" subclass of BaseFeatureAdaptor");
return undef;
}
#_columns
#
# Args : none
# Example : $tablename = $self->_columns()
# Description: ABSTRACT PROTECTED Subclasses are responsible for implementing
# this method. It should return a list of columns to be used
# for feature creation
# Returntype : list of strings
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
#
sub _columns {
my $self = shift;
throw("abstract method _columns not defined by implementing" .
" subclass of BaseFeatureAdaptor");
}
# _default_where_clause
#
# Arg [1] : none
# Example : none
# Description: May be overridden to provide an additional where constraint to
# the SQL query which is generated to fetch feature records.
# This constraint is always appended to the end of the generated
# where clause
# Returntype : string
# Exceptions : none
# Caller : generic_fetch
#
sub _default_where_clause {
my $self = shift;
return '';
}
# _left_join
# Arg [1] : none
# Example : none
# Description: Can be overridden by a subclass to specify any left joins
# which should occur. The table name specigfied in the join
# must still be present in the return values of
# Returntype : a {'tablename' => 'join condition'} pair
# Exceptions : none
# Caller : general
#
sub _left_join {
my $self = shift;
return ();
}
#_final_clause
# Arg [1] : none
# Example : none
# Description: May be overriden to provide an additional clause to the end
# of the SQL query used to fetch feature records.
# This is useful to add a required ORDER BY clause to the
# query for example.
# Returntype : string
# Exceptions : none
# Caller : generic_fetch
sub _final_clause {
my $self = shift;
return '';
}
#_objs_from_sth
# Arg [1] : DBI::row_hashref $hashref containing key-value pairs
# for each of the columns specified by the _columns method
# Example : my @feats = $self->_obj_from_hashref
# Description: ABSTRACT PROTECTED The subclass is responsible for implementing
# this method. It should take in a DBI row hash reference and
# return a list of created features in contig coordinates.
# Returntype : list of Bio::EnsEMBL::*Features in contig coordinates
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
sub _objs_from_sth {
my $self = shift;
throw("abstract method _obj_from_sth not defined by implementing"
. " subclass of BaseFeatureAdaptor");
}
1;
......@@ -71,217 +71,6 @@ sub new {
}
# _straight_join
# Arg [1] : (optional) boolean $new_val
# Example : $self->_straight_join(1);
# $self->generic_fetch($constraint);
# $self->_straight_join(0);
# Description: PROTECTED Getter/Setter that turns on/off the use of
# a straight join in queries.
# Returntype : boolean
# Exceptions : none
# Caller : general
sub _straight_join {
my $self = shift;
if(@_) {
$self->{'_straight_join'} = shift;
}
return $self->{'_straight_join'};
}
=head2 generic_fetch
Arg [1] : (optional) string $constraint
An SQL query constraint (i.e. part of the WHERE clause)
Arg [2] : (optional) Bio::EnsEMBL::AssemblyMapper $mapper
A mapper object used to remap features
as they are retrieved from the database
Arg [3] : (optional) Bio::EnsEMBL::Slice $slice
A slice that features should be remapped to
Example : $fts = $a->generic_fetch('contig_id in (1234, 1235)', 'Swall');
Description: Performs a database fetch and returns feature objects in
contig coordinates.
Returntype : listref of Bio::EnsEMBL::SeqFeature in contig coordinates
Exceptions : none
Caller : BaseFeatureAdaptor, ProxyDnaAlignFeatureAdaptor::generic_fetch
=cut
sub generic_fetch {
my ($self, $constraint, $mapper, $slice) = @_;
my @tabs = $self->_tables;
my $columns = join(', ', $self->_columns());
my $db = $self->db();
#
# Construct a left join statement if one was defined, and remove the
# left-joined table from the table list
#
my @left_join_list = $self->_left_join();
my $left_join = '';
my @tables;
if(@left_join_list) {
my %left_join_hash = map { $_->[0] => $_->[1] } @left_join_list;
while(my $t = shift @tabs) {
if( exists $left_join_hash{ $t->[0] } ) {
my $condition = $left_join_hash{ $t->[0] };
my $syn = $t->[1];
$left_join .= "LEFT JOIN\n ".$t->[0]." $syn ON $condition ";
} else {
push @tables, $t;
}
}
} else {
@tables = @tabs;
}
my $straight_join = '';
if($self->_straight_join()) {
$straight_join = "STRAIGHT_JOIN";
}
#construct a nice table string like 'table1 t1, table2 t2'
my $tablenames = join(', ', map({ join(' ', @$_) } @tables));
my $sql = "SELECT $straight_join $columns\n FROM $tablenames $left_join";
my $default_where = $self->_default_where_clause;
my $final_clause = $self->_final_clause;
#append a where clause if it was defined
if($constraint) {
$sql .= "\n WHERE $constraint ";
if($default_where) {
$sql .= " AND\n $default_where ";
}
} elsif($default_where) {
$sql .= "\n WHERE $default_where ";
}
#append additional clauses which may have been defined
$sql .= "\n$final_clause";
my $sth = $db->dbc->prepare($sql);
$sth->execute;
my $res = $self->_objs_from_sth($sth, $mapper, $slice);
return $res;
}
=head2 fetch_by_dbID
Arg [1] : int $id
The unique database identifier for the feature to be obtained
Example : $feat = $adaptor->fetch_by_dbID(1234));
$feat = $feat->transform('contig');
Description: Returns the feature created from the database defined by the
the id $id. The feature will be returned in its native
coordinate system. That is, the coordinate system in which it
is stored in the database. In order to convert it to a
particular coordinate system use the transfer() or transform()
method. If the feature is not found in the database then
undef is returned instead
Returntype : Bio::EnsEMBL::Feature or undef
Exceptions : thrown if $id arg is not provided
does not exist
Caller : general
=cut
sub fetch_by_dbID{
my ($self,$id) = @_;
throw("id argument is required") if(!defined $id);
#construct a constraint like 't1.table1_id = 123'
my @tabs = $self->_tables;
my ($name, $syn) = @{$tabs[0]};
my $constraint = "${syn}.${name}_id = $id";
#Should only be one
my ($feat) = @{$self->generic_fetch($constraint)};
return undef if(!$feat);
return $feat;
}
=head2 fetch_all_by_dbID_list
Arg [1] : listref of ints $id_list
The unique database identifiers for the features to be obtained
Example : @feats = @{$adaptor->fetch_by_dbID_list([1234, 2131, 982]))};
Description: Returns the features created from the database defined by the
the ids in contained in the id list $id_list. The features
will be returned in their native coordinate system. That is,
the coordinate system in which they are stored in the database.
In order to convert the features to a particular coordinate
system use the transfer() or transform() method. If none of the
features are found in the database a reference to an empty
list is returned.
Returntype : listref of Bio::EnsEMBL::Features
Exceptions : thrown if $id arg is not provided
does not exist
Caller : general
=cut
sub fetch_all_by_dbID_list {
my ($self,$id_list) = @_;
if(!defined($id_list) || ref($id_list) ne 'ARRAY') {
throw("id_list list reference argument is required");
}
return [] if(!@$id_list);
my @out;
#construct a constraint like 't1.table1_id = 123'
my @tabs = $self->_tables;
my ($name, $syn) = @{$tabs[0]};
# mysql is faster and we ensure that we do not exceed the max query size by
# splitting large queries into smaller queries of 200 ids
my $max_size = 200;
while(@$id_list) {
my @ids;
if(@$id_list > $max_size) {
@ids = splice(@$id_list, 0, $max_size);
} else {
@ids = splice(@$id_list, 0);
}
my $id_str;
if(@ids > 1) {
$id_str = " IN (" . join(',', @ids). ")";
} else {
$id_str = " = " . $ids[0];
}
my $constraint = "${syn}.${name}_id $id_str";
push @out, @{$self->generic_fetch($constraint)};
}
return \@out;
}
=head2 fetch_all_by_Slice
Arg [1] : Bio::EnsEMBL::Slice $slice
......@@ -914,137 +703,6 @@ sub remove_by_Slice {
}
#_tables
#
# Args : none
# Example : $tablename = $self->_table_name()
# Description: ABSTRACT PROTECTED Subclasses are responsible for implementing
# this method. It should list of [tablename, alias] pairs.
# Additionally the primary table (with the dbID, analysis_id, and
# score) should be the first table in the list.
# e.g:
# ( ['repeat_feature', 'rf'],
# ['repeat_consensus', 'rc']);
# used to obtain features.
# Returntype : list of [tablename, alias] pairs
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
#
sub _tables {
my $self = shift;
throw("abstract method _tables not defined by implementing" .
" subclass of BaseFeatureAdaptor");
return undef;
}
#_columns
#
# Args : none
# Example : $tablename = $self->_columns()
# Description: ABSTRACT PROTECTED Subclasses are responsible for implementing
# this method. It should return a list of columns to be used
# for feature creation
# Returntype : list of strings
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
#
sub _columns {
my $self = shift;
throw("abstract method _columns not defined by implementing" .
" subclass of BaseFeatureAdaptor");
}
# _default_where_clause
#
# Arg [1] : none
# Example : none
# Description: May be overridden to provide an additional where constraint to
# the SQL query which is generated to fetch feature records.
# This constraint is always appended to the end of the generated
# where clause
# Returntype : string
# Exceptions : none
# Caller : generic_fetch
#
sub _default_where_clause {
my $self = shift;
return '';
}
# _left_join
# Arg [1] : none
# Example : none
# Description: Can be overridden by a subclass to specify any left joins
# which should occur. The table name specigfied in the join
# must still be present in the return values of
# Returntype : a {'tablename' => 'join condition'} pair
# Exceptions : none
# Caller : general
#
sub _left_join {
my $self = shift;
return ();
}
#_final_clause
# Arg [1] : none
# Example : none
# Description: May be overriden to provide an additional clause to the end
# of the SQL query used to fetch feature records.
# This is useful to add a required ORDER BY clause to the
# query for example.
# Returntype : string
# Exceptions : none
# Caller : generic_fetch
sub _final_clause {
my $self = shift;
return '';
}
#_objs_from_sth
# Arg [1] : DBI::row_hashref $hashref containing key-value pairs
# for each of the columns specified by the _columns method
# Example : my @feats = $self->_obj_from_hashref
# Description: ABSTRACT PROTECTED The subclass is responsible for implementing
# this method. It should take in a DBI row hash reference and
# return a list of created features in contig coordinates.
# Returntype : list of Bio::EnsEMBL::*Features in contig coordinates
# Exceptions : thrown if not implemented by subclass
# Caller : BaseFeatureAdaptor::generic_fetch
sub _objs_from_sth {
my $self = shift;
throw("abstract method _obj_from_sth not defined by implementing"
. " subclass of BaseFeatureAdaptor");
}
#
# Internal function. Allows the max feature length which is normally
# retrieved from the meta_coord table to be overridden. This allows
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment