AltAlleleGroupAdaptor.pm 13 KB
Newer Older
1 2
=head1 LICENSE

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Copyright [1999-2013] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

=cut
18 19 20 21 22 23



=head1 CONTACT

  Please email comments or questions to the public Ensembl
Magali Ruffier's avatar
Magali Ruffier committed
24
  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 26

  Questions may also be sent to the Ensembl help desk at
Magali Ruffier's avatar
Magali Ruffier committed
27
  <http://www.ensembl.org/Help/Contact>.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

=cut

=head1 NAME

Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor - Adaptor for the manipulation of
Alternative allele groupings

=head1 SYNOPSIS

  use Bio::EnsEMBL::AltAlleleGroup;
  use Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor;
  
  my $aag_adaptor = Bio::EnsEMBL::Registry->get_DBAdaptor("Human","core","AltAlleleGroup");
  
  # For a known Gene, find the reference alternative allele
44
  my $aag = $aag_adaptor->fetch_by_gene_id($gene->dbID);
45 46 47
  my $reference_gene = $aag->get_ref_Gene;
  
  # Get a list of AltAlleleGroups
48 49
  my $list = $aag_adaptor->fetch_all_('IS_REPRESENTATIVE');
  $list = $aag_adaptor->fetch_all();
50 51 52
  
  my $dbID = $aag_adaptor->store($aag);
  
53
  $aag = $aag_adaptor->fetch_by_dbID($dbID);
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
  $aag_adaptor->remove($aag);

=head1 DESCRIPTION

  The AltAlleleGroupAdaptor provides CRUD for AltAlleleGroup objects. It allows
  groups of alleles to be retrieved by group and gene ids.

=cut

package Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor;

use strict;
use warnings;

use base qw/Bio::EnsEMBL::DBSQL::BaseAdaptor/;

use Bio::EnsEMBL::AltAlleleGroup;
71
use Bio::EnsEMBL::Utils::Exception qw/throw deprecate/;
72
use Bio::EnsEMBL::Utils::Scalar qw/assert_ref/;
73 74 75 76 77
use DBI qw( :sql_types );

=head2 fetch_all_Groups

  Arg[1]      : (optional) String - type of group
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
  Description : DEPRECATED. Please use fetch_all()
  Returntype  : ArrayRef of Bio::EnsEMBL::AltAlleleGroup

=cut

sub fetch_all_Groups {
    my ($self, $type) = @_;
    deprecate('Please use fetch_all()');
    return $self->fetch_all($type);
}

=head2 fetch_all

  Arg[1]      : (optional) String - type of group
                Restrict group fetches to just one type. Technically it selects 
                out mixed-annotation groups where a single member contains that type.
94
  Description : Fetches all the alt-allele groups, creates objects to represent
95 96 97 98
                them and returns them in a list. Specifying a group type 
                identifies all groups containing a member of this type. It 
                does not filter out the other members
                
99 100
                Multispecies support is triggered by the is_multispecies flag
                and species_id of the DBAdaptor.
101 102
  Returntype  : ArrayRef of Bio::EnsEMBL::AltAlleleGroup

103 104
=cut

105
sub fetch_all {
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
    my $self = shift;
    my $type = shift;

    $type = uc($type) if ($type);
    
    my @group_list = ();
    my @members;
    
    my $species_id;
    my $get_all_sql;
    if ($self->db->is_multispecies()) {
        # multispecies databases must be restricted in their treatment
        $species_id = $self->db->species_id;
        
        if ($type) {
            $get_all_sql = q(
                SELECT DISTINCT alt_allele_group_id FROM alt_allele a
                JOIN (gene g, seq_region s, coord_system c, alt_allele_attrib b)
                ON (
                    c.coord_system_id = s.coord_system_id 
                    AND s.seq_region_id = g.seq_region_id
                    AND g.gene_id = a.gene_id
                    AND a.alt_allele_id = b.alt_allele_id
                )
                WHERE c.species_id = ? AND b.attrib = ?
            );
        }
133 134 135 136 137 138 139 140 141 142 143 144
        else {
            $get_all_sql = q(
                SELECT DISTINCT alt_allele_group_id FROM alt_allele a
                JOIN (gene g, seq_region s, coord_system c)
                ON (
                    c.coord_system_id = s.coord_system_id 
                    AND s.seq_region_id = g.seq_region_id
                    AND g.gene_id = a.gene_id
                )
                WHERE c.species_id = ? 
            );
        }
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
    } else {
        if ($type) {
            $get_all_sql = q(SELECT DISTINCT alt_allele_group_id 
                FROM alt_allele a, alt_allele_attrib b
                WHERE a.alt_allele_id = b.alt_allele_id
                AND b.attrib = ?);
        } else {
            $get_all_sql = q(SELECT DISTINCT alt_allele_group_id FROM alt_allele);
        }
       
    }
    
    my $sth = $self->prepare($get_all_sql);
    
    my $x = 1;
    if ($self->db->is_multispecies()) {
        $sth->bind_param($x,$species_id, SQL_INTEGER);
        $x++;
    }
    
    $sth->bind_param($x,$type, SQL_VARCHAR) if ($type);
    eval { $sth->execute() };
    if ($@) {
        throw("Query error in AltAlleleGroupAdaptor: $@");
    }
    
    
    my $group_id;    
    $sth->bind_col(1, \$group_id );
    
    while ( $sth->fetch() ) {
176
        my $aag = $self->fetch_by_dbID($group_id);
177 178 179 180 181 182 183 184 185
        push @group_list, $aag;
    }
    $sth->finish;
    return \@group_list;
}

=head2 fetch_all_Groups_by_type

  Arg[1]      : String - type of group
186 187 188
  Description : DEPRECATED. Please use fetch_all()
  Returntype  : ArrayRef of Bio::EnsEMBL::AltAlleleGroup

189 190 191
=cut

sub fetch_all_Groups_by_type {
192 193 194
    my ($self, $type) = @_;
    deprecate('Please use fetch_all()');
    my $group_list = $self->fetch_all($type);
195 196 197 198 199
    return $group_list;
}

=head2 fetch_Group_by_id

200 201 202 203 204 205 206 207 208 209 210 211 212 213
  Arg[1]      : AltAlleleGroup dbID.
  Description : DEPRECATED. Please use fetch_by_dbID
  Returntype  : Bio::EnsEMBL::AltAlleleGroup

=cut

sub fetch_Group_by_id {
    my ($self, $group_id) = @_;
    deprecate('Please use fetch_by_dbID()');
    return $self->fetch_by_dbID($group_id);
}

=head2 fetch_by_dbID

214 215 216 217 218 219 220
  Arg[1]      : AltAlleleGroup dbID.
  Description : Creates and returns an AltAlleleGroup for the given group id
                
  Returntype  : Bio::EnsEMBL::AltAlleleGroup

=cut

221
sub fetch_by_dbID {
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
    my $self = shift;
    my $group_id = shift;
    
    my @members;
    
    my $get_alt_allele_sql = q(
        SELECT alt_allele_id, gene_id FROM alt_allele
        WHERE alt_allele_group_id = ? ORDER BY alt_allele_id
    );
    my $sth = $self->prepare($get_alt_allele_sql);
    
    $sth->bind_param(1,$group_id, SQL_INTEGER);
    
    $sth->execute();
    my ($alt_allele_id, $gene_id);
    $sth->bind_columns( \($alt_allele_id,$gene_id) );
    
    my $attrib_fetch = q(
        SELECT attrib FROM alt_allele_attrib WHERE alt_allele_id = ?
    );
    my $attrib_sth = $self->prepare($attrib_fetch);
    my $attrib;
    
    while ($sth->fetch()) {
        # fetch alt_allele attributes
        $attrib_sth->execute($alt_allele_id);
        $attrib_sth->bind_col(1,\$attrib);
        my %attrib_list;
        while ($attrib_sth->fetch) {
            $attrib_list{$attrib} = 1;
        }
        push @members,[$gene_id, \%attrib_list];
    }
    $attrib_sth->finish;
    $sth->finish;
    
    if ($group_id && scalar(@members) > 0) {
        my $aag = Bio::EnsEMBL::AltAlleleGroup->new(
            -dbID => $group_id,
            -MEMBERS => \@members,
            -ADAPTOR => $self,
        );
        return $aag;
    }
    return;
}

269 270 271 272 273 274 275 276 277
=head2 fetch_Group_by_Gene_dbID

  Arg[1]      : Integer Gene ID of the member to query by
  Description : DEPRECATED. Please use fetch_by_gene_id 
  Returntype  : Bio::EnsEMBL::AltAlleleGroup

=cut


278
sub fetch_Group_by_Gene_dbID {
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
    my ($self, $gene_id) = @_;
    deprecate('Please use fetch_by_gene_id()');
    return $self->fetch_by_gene_id($gene_id);
}

=head2 fetch_by_gene_id

  Arg[1]      : Integer Gene ID of the member to query by
  Description : Creates and returns an AltAlleleGroup which contains
                the specified gene member                
  Returntype  : Bio::EnsEMBL::AltAlleleGroup

=cut

sub fetch_by_gene_id {
    my ($self, $gene_id) = @_;

296 297 298 299 300 301 302 303 304 305 306 307 308
    my $gene_id_sql = q(
        SELECT alt_allele_group_id FROM alt_allele
        WHERE gene_id = ?
    );
    my $sth = $self->prepare($gene_id_sql);
    $sth->bind_param(1,$gene_id, SQL_INTEGER);
    
    my $group_id;
    $sth->execute();
    $sth->bind_col(1,\$group_id);
    $sth->fetch;
    $sth->finish;
    if (!$@ && $group_id) {
309
        return $self->fetch_by_dbID($group_id);
310
    }
311
    return;
312 313 314 315
}

=head2 store

316
  Arg[1]     : Bio::EnsEMBL::AltAlleleGroup
317 318 319 320 321 322 323 324 325 326
  Description: Used for persisting new groups to the database.
               It updates the dbID of the object handed to it to match the
               database.
  Returntype : Integer Alt Allele Group id

=cut

sub store {
    my $self = shift;
    my $allele_group = shift;
327 328 329 330 331 332

    assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');
    if ($allele_group->size < 2) {
        warning('At least 2 genes must be provided to construct alternative alleles. Ignoring.');
        return;
    }
333
    
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
    my $helper = $self->dbc()->sql_helper();
    my $dbID = $allele_group->dbID;
    
    my $new_group_sql = 'INSERT INTO alt_allele_group (alt_allele_group_id) VALUES (?)';
    my $existing_group_sql = 'SELECT count(*) FROM alt_allele_group WHERE alt_allele_group_id = ?';

    my $already_exists = $helper->execute_single_result(-SQL => $existing_group_sql, -PARAMS => [[$dbID, SQL_INTEGER]]);
    
    # If the ID is not already there then we need to add one
    if($already_exists == 0) {
        $helper->execute_update(-SQL => $new_group_sql, -CALLBACK => sub {
            my ($sth, $dbh, $rv) = @_;
            if($rv) {
                my $id = $dbh->last_insert_id(undef, undef, 'alt_allele_group', 'alt_allele_group_id');
                $dbID = $id;
            }
350
            return;
351 352 353 354 355 356 357 358 359
        });
    }
    
    my $sth = $self->prepare("INSERT INTO alt_allele (alt_allele_id, alt_allele_group_id, gene_id) VALUES (?,?,?)");
    my $attrib_sth = $self->prepare("INSERT INTO alt_allele_attrib (alt_allele_id,attrib) VALUES (?,?)");
    
    foreach my $allele (@{ $allele_group->get_all_members() }) {
        my $gene_id = $allele->[0];
        my %flags = %{$allele->[1]};
360
        
361 362 363 364 365 366 367 368 369
        $sth->bind_param(1, undef, SQL_INTEGER);
        $sth->bind_param(2, $dbID, SQL_INTEGER);
        $sth->bind_param(3, $gene_id, SQL_INTEGER);
        my $altered_rows = $sth->execute();
        my $allele_id;
        if ($altered_rows > 0) {
            $allele_id = $self->last_insert_id(); # all alleles get added to the same alt_allele_id group
        } else {
            throw("Creation of new alt_allele failed: $@");
370 371 372
        }
        
            
373 374 375 376
        foreach my $flag (keys %flags) {
            $attrib_sth->bind_param(1, $allele_id);
            $attrib_sth->bind_param(2, $flag);
            $attrib_sth->execute();
377 378
        }
    }
379 380 381 382 383 384 385
    if ($@) {throw ("Problem inserting new AltAlleleGroup into database: $@");}
    $sth->finish;
    $attrib_sth->finish;
    
    $allele_group->dbID($dbID);
    
    return $dbID;
386 387 388 389 390 391 392 393 394 395 396 397 398 399
}

=head2 update

  Arg [1]    : AltAlleleGroup 
  Description: Removes the existing DB record of an AltAlleleGroup and stores 
               the altered version.
  Returntype : Integer - the return value of the store method, viz. whether the
               insert was successful.
=cut

sub update {
    my $self = shift;
    my $allele_group = shift;
400 401 402 403
    assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');
    throw "Cannot update an AltAlleleGroup without a dbID. AltAlleleGroups should be fetched from the DB prior to updating them" if ! $allele_group->dbID();
    my $keep_group = 1;
    $self->remove($allele_group, $keep_group);
404 405 406 407 408 409
    return $self->store($allele_group);
}

=head2 remove

  Arg [1]    : The AltAlleleGroup to remove.
410
  Arg [2]    : Boolean indicates if the entry in alt_allele_group should be retained or remove. Defaults to removing the entry
411 412 413 414 415 416 417
  Example    : $aaga->remove($alt_allele_group);
  Description: This removes an AltAlleleGroup from all tables of the database. 
  Exceptions : None
  
=cut

sub remove {
418 419 420 421 422 423 424 425 426 427 428 429 430
    my ($self, $allele_group, $keep_group) = @_;
    assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');

    my $helper = $self->dbc()->sql_helper();
    my $delete_attribs_sql = 'DELETE aaa FROM alt_allele_attrib aaa join alt_allele aa using (alt_allele_id) where alt_allele_group_id =?';
    my $delete_alt_alleles_sql = 'DELETE FROM alt_allele where alt_allele_group_id =?';
    my $delete_group_sql = 'DELETE from alt_allele_group where alt_allele_group_id =?';
    my $params = [[$allele_group->dbID, SQL_INTEGER]];

    $helper->execute_update(-SQL => $delete_attribs_sql, -PARAMS => $params);
    $helper->execute_update(-SQL => $delete_alt_alleles_sql, -PARAMS => $params);
    if(! $keep_group) {
        $helper->execute_update(-SQL => $delete_group_sql, -PARAMS => $params);
431 432
    }

433
    return;
434 435 436 437 438 439
}

sub _tables {
    return (['alt_allele', 'a'], ['alt_allele_group', 'g'], ['alt_allele_attrib', 'b']);
}

440
1;