ensembl-hive  2.8.1
AltAlleleGroupAdaptor.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 =cut
19 
20 
21 
22 =head1 CONTACT
23 
24  Please email comments or questions to the public Ensembl
25  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
26 
27  Questions may also be sent to the Ensembl help desk at
28  <http://www.ensembl.org/Help/Contact>.
29 
30 =cut
31 
32 =head1 NAME
33 
34 Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor - Adaptor for the manipulation of
35 Alternative allele groupings
36 
37 =head1 SYNOPSIS
38 
41 
42  my $aag_adaptor = Bio::EnsEMBL::Registry->get_DBAdaptor("Human","core","AltAlleleGroup");
43 
44  # For a known Gene, find the reference alternative allele
45  my $aag = $aag_adaptor->fetch_by_gene_id($gene->dbID);
46  my $reference_gene = $aag->get_ref_Gene;
47 
48  # Get a list of AltAlleleGroups
49  my $list = $aag_adaptor->fetch_all_('IS_REPRESENTATIVE');
50  $list = $aag_adaptor->fetch_all();
51 
52  my $dbID = $aag_adaptor->store($aag);
53 
54  $aag = $aag_adaptor->fetch_by_dbID($dbID);
55  $aag_adaptor->remove($aag);
56 
57 =head1 DESCRIPTION
58 
59  The AltAlleleGroupAdaptor provides CRUD for AltAlleleGroup objects. It allows
60  groups of alleles to be retrieved by group and gene ids.
61 
62 =cut
63 
64 package Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor;
65 
66 use strict;
67 use warnings;
68 
70 
72 use Bio::EnsEMBL::Utils::Exception qw/throw warning/;
73 use Bio::EnsEMBL::Utils::Scalar qw/assert_ref/;
74 use DBI qw( :sql_types );
75 
76 =head2 fetch_all
77 
78  Arg[1] : (optional) String - type of group
79  Restrict group fetches to just one type. Technically it selects
80  out mixed-annotation groups where a single member contains that type.
81  Description : Fetches all the alt-allele groups, creates objects to represent
82  them and returns them in a list. Specifying a group type
83  identifies all groups containing a member of this type. It
84  does not filter out the other members
85 
86  Multispecies support is triggered by the is_multispecies flag
87  and species_id of the DBAdaptor.
88  Returntype : ArrayRef of Bio::EnsEMBL::AltAlleleGroup
89 
90 =cut
91 
92 sub fetch_all {
93  my $self = shift;
94  my $type = shift;
95 
96  $type = uc($type) if ($type);
97 
98  my @group_list = ();
99  my @members;
100 
101  my $species_id;
102  my $get_all_sql;
103  if ($self->db->is_multispecies()) {
104  # multispecies databases must be restricted in their treatment
105  $species_id = $self->db->species_id;
106 
107  if ($type) {
108  $get_all_sql = q(
109  SELECT DISTINCT alt_allele_group_id
110  FROM alt_allele a
111  JOIN gene g ON g.gene_id = a.gene_id
112  JOIN seq_region s ON s.seq_region_id = g.seq_region_id
113  JOIN coord_system c ON c.coord_system_id = s.coord_system_id
114  JOIN alt_allele_attrib b ON a.alt_allele_id = b.alt_allele_id
115  WHERE c.species_id = ? AND b.attrib = ?
116  );
117  } else {
118  $get_all_sql = q(
119  SELECT DISTINCT alt_allele_group_id
120  FROM alt_allele a
121  JOIN gene g ON g.gene_id = a.gene_id
122  JOIN seq_region s ON s.seq_region_id = g.seq_region_id
123  JOIN coord_system c ON c.coord_system_id = s.coord_system_id
124  WHERE c.species_id = ?
125  );
126  }
127  } else {
128  if ($type) {
129  $get_all_sql = q(SELECT DISTINCT alt_allele_group_id
130  FROM alt_allele a, alt_allele_attrib b
131  WHERE a.alt_allele_id = b.alt_allele_id
132  AND b.attrib = ?);
133  } else {
134  $get_all_sql = q(SELECT DISTINCT alt_allele_group_id FROM alt_allele);
135  }
136 
137  }
138 
139  my $sth = $self->prepare($get_all_sql);
140 
141  my $x = 1;
142  if ($self->db->is_multispecies()) {
143  $sth->bind_param($x,$species_id, SQL_INTEGER);
144  $x++;
145  }
146 
147  $sth->bind_param($x,$type, SQL_VARCHAR) if ($type);
148  eval { $sth->execute() };
149  if ($@) {
150  throw("Query error in AltAlleleGroupAdaptor: $@");
151  }
152 
153 
154  my $group_id;
155  $sth->bind_col(1, \$group_id );
156 
157  while ( $sth->fetch() ) {
158  my $aag = $self->fetch_by_dbID($group_id);
159  push @group_list, $aag;
160  }
161  $sth->finish;
162  return \@group_list;
163 }
164 
165 =head2 fetch_by_dbID
166 
167  Arg[1] : AltAlleleGroup dbID.
168  Description : Creates and returns an AltAlleleGroup for the given group id
169 
170  Returntype : Bio::EnsEMBL::AltAlleleGroup
171 
172 =cut
173 
174 sub fetch_by_dbID {
175  my $self = shift;
176  my $group_id = shift;
177 
178  my @members;
179 
180  my $get_alt_allele_sql = q(
181  SELECT alt_allele_id, gene_id FROM alt_allele
182  WHERE alt_allele_group_id = ? ORDER BY alt_allele_id
183  );
184  my $sth = $self->prepare($get_alt_allele_sql);
185 
186  $sth->bind_param(1,$group_id, SQL_INTEGER);
187 
188  $sth->execute();
189  my ($alt_allele_id, $gene_id);
190  $sth->bind_columns( \($alt_allele_id,$gene_id) );
191 
192  my $attrib_fetch = q(
193  SELECT attrib FROM alt_allele_attrib WHERE alt_allele_id = ?
194  );
195  my $attrib_sth = $self->prepare($attrib_fetch);
196  my $attrib;
197 
198  while ($sth->fetch()) {
199  # fetch alt_allele attributes
200  $attrib_sth->execute($alt_allele_id);
201  $attrib_sth->bind_col(1,\$attrib);
202  my %attrib_list;
203  while ($attrib_sth->fetch) {
204  $attrib_list{$attrib} = 1;
205  }
206  push @members,[$gene_id, \%attrib_list];
207  }
208  $attrib_sth->finish;
209  $sth->finish;
210 
211  if ($group_id && scalar(@members) > 0) {
213  -dbID => $group_id,
214  -MEMBERS => \@members,
215  -ADAPTOR => $self,
216  );
217  return $aag;
218  }
219  return;
220 }
221 
222 =head2 fetch_by_gene_id
223 
224  Arg[1] : Integer Gene ID of the member to query by
225  Description : Returns an AltAlleleGroup which contains
226  the specified gene member
227  Returntype : Bio::EnsEMBL::AltAlleleGroup
228 
229 =cut
230 
231 sub fetch_by_gene_id {
232  my ($self, $gene_id) = @_;
233 
234  my $aag_list = $self->fetch_all_by_gene_id($gene_id);
235 
236  return unless @$aag_list;
237 
238  # return first group from list
239  my $group_id = $aag_list->[0]->dbID;
240  return $self->fetch_by_dbID($group_id);
241 }
242 
243 =head2 fetch_all_by_gene_id
244 
245  Arg[1] : Integer Gene ID of the member to query by
246  Description : Returns an array of one or more AltAlleleGroups,
247  which each contain the specified gene member
248  Returntype : Array of Bio::EnsEMBL::AltAlleleGroup objects
249 
250 =cut
251 
252 sub fetch_all_by_gene_id {
253  my ($self, $gene_id) = @_;
254 
255  my $gene_id_sql = q(
256  SELECT alt_allele_group_id FROM alt_allele
257  WHERE gene_id = ? ORDER BY alt_allele_group_id
258  );
259  my $sth = $self->prepare($gene_id_sql);
260  $sth->bind_param(1,$gene_id, SQL_INTEGER);
261  $sth->execute;
262 
263  my $group_ids = $sth->fetchall_arrayref();
264  $sth->finish;
265 
266  my @aag;
267  if (! $@ && @$group_ids) {
268  foreach my $group (@$group_ids) {
269  push(@aag, $self->fetch_by_dbID($group->[0]));
270  }
271  }
272  return \@aag;
273 }
274 
275 =head2 store
276 
278  Description: Used for persisting new groups to the database.
279  It updates the dbID of the object handed to it to match the
280  database.
281  Returntype : Integer Alt Allele Group id
282 
283 =cut
284 
285 sub store {
286  my $self = shift;
287  my $allele_group = shift;
288 
289  assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');
290  if ($allele_group->size < 2) {
291  warning('At least 2 genes must be provided to construct alternative alleles. Ignoring.');
292  return;
293  }
294 
295  my $helper = $self->dbc()->sql_helper();
296  my $dbID = $allele_group->dbID;
297 
298  my $new_group_sql = 'INSERT INTO alt_allele_group (alt_allele_group_id) VALUES (?)';
299  my $existing_group_sql = 'SELECT count(*) FROM alt_allele_group WHERE alt_allele_group_id = ?';
300 
301  my $already_exists = $helper->execute_single_result(-SQL => $existing_group_sql, -PARAMS => [[$dbID, SQL_INTEGER]]);
302 
303  # If the ID is not already there then we need to add one
304  if($already_exists == 0) {
305  $helper->execute_update(-SQL => $new_group_sql, -CALLBACK => sub {
306  my ($sth, $dbh, $rv) = @_;
307  if($rv) {
308  my $id = $dbh->last_insert_id(undef, undef, 'alt_allele_group', 'alt_allele_group_id');
309  $dbID = $id;
310  }
311  return;
312  });
313  }
314 
315  my $sth = $self->prepare("INSERT INTO alt_allele (alt_allele_id, alt_allele_group_id, gene_id) VALUES (?,?,?)");
316  my $attrib_sth = $self->prepare("INSERT INTO alt_allele_attrib (alt_allele_id,attrib) VALUES (?,?)");
317  my $check_exists_sth = $self->prepare("SELECT alt_allele_id FROM alt_allele WHERE gene_id = ?");
318 
319  foreach my $allele (@{ $allele_group->get_all_members() }) {
320  my $gene_id = $allele->[0];
321  my %flags = %{$allele->[1]};
322  my $allele_id;
323 
324 # Check if gene is not already stored
325 # Return allele_id if it is
326  $check_exists_sth->bind_param(1, $gene_id, SQL_INTEGER);
327  $check_exists_sth->execute();
328  $check_exists_sth->bind_col(1, \$allele_id);
329  if ($check_exists_sth->fetch() ) {
330  return $allele_id;
331  }
332 
333  $sth->bind_param(1, undef, SQL_INTEGER);
334  $sth->bind_param(2, $dbID, SQL_INTEGER);
335  $sth->bind_param(3, $gene_id, SQL_INTEGER);
336  my $altered_rows = $sth->execute();
337  if ($altered_rows > 0) {
338  $allele_id = $self->last_insert_id(); # all alleles get added to the same alt_allele_id group
339  } else {
340  throw("Creation of new alt_allele failed: $@");
341  }
342 
343 
344  foreach my $flag (keys %flags) {
345  $attrib_sth->bind_param(1, $allele_id);
346  $attrib_sth->bind_param(2, $flag);
347  $attrib_sth->execute();
348  }
349  }
350  if ($@) {throw ("Problem inserting new AltAlleleGroup into database: $@");}
351  $sth->finish;
352  $attrib_sth->finish;
353  $check_exists_sth->finish;
354 
355  $allele_group->dbID($dbID);
356 
357  return $dbID;
358 }
359 
360 =head2 update
361 
362  Arg [1] : AltAlleleGroup
363  Description: Removes the existing DB record of an AltAlleleGroup and stores
364  the altered version.
365  Returntype : Integer - the return value of the store method, viz. whether the
366  insert was successful.
367 =cut
368 
369 sub update {
370  my $self = shift;
371  my $allele_group = shift;
372  assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');
373  throw "Cannot update an AltAlleleGroup without a dbID. AltAlleleGroups should be fetched from the DB prior to updating them" if ! $allele_group->dbID();
374  my $keep_group = 1;
375  $self->remove($allele_group, $keep_group);
376  return $self->store($allele_group);
377 }
378 
379 =head2 remove
380 
381  Arg [1] : The AltAlleleGroup to remove.
382  Arg [2] : Boolean indicates if the entry in alt_allele_group should be retained or remove. Defaults to removing the entry
383  Example : $aaga->remove($alt_allele_group);
384  Description: This removes an AltAlleleGroup from all tables of the database.
385  Exceptions : None
386 
387 =cut
388 
389 sub remove {
390  my ($self, $allele_group, $keep_group) = @_;
391  assert_ref($allele_group, 'Bio::EnsEMBL::AltAlleleGroup', 'allele_group');
392 
393  my $helper = $self->dbc()->sql_helper();
394  my $delete_attribs_sql;
395  if ($self->dbc->driver() eq 'mysql') {
396  $delete_attribs_sql = q{
397  DELETE aaa
398  FROM alt_allele_attrib aaa
399  JOIN alt_allele aa using (alt_allele_id)
400  where alt_allele_group_id =?
401  };
402  }
403  else {
404  $delete_attribs_sql = q{
405  DELETE FROM alt_allele_attrib WHERE alt_allele_id IN (
406  SELECT alt_allele_id FROM alt_allele WHERE alt_allele_group_id = ?
407  )
408  };
409  }
410  my $delete_alt_alleles_sql = 'DELETE FROM alt_allele where alt_allele_group_id =?';
411  my $delete_group_sql = 'DELETE from alt_allele_group where alt_allele_group_id =?';
412  my $params = [[$allele_group->dbID, SQL_INTEGER]];
413 
414  $helper->execute_update(-SQL => $delete_attribs_sql, -PARAMS => $params);
415  $helper->execute_update(-SQL => $delete_alt_alleles_sql, -PARAMS => $params);
416  if(! $keep_group) {
417  $helper->execute_update(-SQL => $delete_group_sql, -PARAMS => $params);
418  }
419 
420  return;
421 }
422 
423 sub _tables {
424  return (['alt_allele', 'a'], ['alt_allele_group', 'g'], ['alt_allele_attrib', 'b']);
425 }
426 
427 1;
Bio::EnsEMBL::Storable::dbID
public Int dbID()
Bio::EnsEMBL::DBSQL::DBAdaptor
Definition: DBAdaptor.pm:40
Bio::EnsEMBL::AltAlleleGroup
Definition: AltAlleleGroup.pm:67
Bio::EnsEMBL::Registry
Definition: Registry.pm:113
Bio::EnsEMBL::Registry::get_DBAdaptor
public DBAdaptor get_DBAdaptor()
Bio::EnsEMBL::DBSQL::BaseAdaptor
Definition: BaseAdaptor.pm:71
Bio::EnsEMBL::Utils::Scalar
Definition: Scalar.pm:66
Bio::EnsEMBL::AltAlleleGroup::new
public Bio::EnsEMBL::AltAlleleGroup new()
Bio::EnsEMBL::Utils::Exception
Definition: Exception.pm:68
Bio::EnsEMBL::DBSQL::AltAlleleGroupAdaptor
Definition: AltAlleleGroupAdaptor.pm:36