File Coverage

blib/lib/PomBase/Chobo/ChadoData.pm
Criterion Covered Total %
statement 146 169 86.3
branch 6 12 50.0
condition 1 2 50.0
subroutine 26 31 83.8
pod 0 13 0.0
total 179 227 78.8


line stmt bran cond sub pod time code
1             package PomBase::Chobo::ChadoData;
2              
3             =head1 NAME
4              
5             PomBase::Chobo::ChadoData - Read and store cv/db data from Chado
6              
7             =head1 SYNOPSIS
8              
9             =head1 AUTHOR
10              
11             Kim Rutherford C<< >>
12              
13             =head1 BUGS
14              
15             Please report any bugs or feature requests to C.
16              
17             =head1 SUPPORT
18              
19             You can find documentation for this module with the perldoc command.
20              
21             perldoc PomBase::Chobo::ChadoData
22              
23             =over 4
24              
25             =back
26              
27             =head1 COPYRIGHT & LICENSE
28              
29             Copyright 2012 Kim Rutherford, all rights reserved.
30              
31             This program is free software; you can redistribute it and/or modify it
32             under the same terms as Perl itself.
33              
34             =head1 FUNCTIONS
35              
36             =cut
37              
38             our $VERSION = '0.038'; # VERSION
39              
40 1     1   7 use Mouse;
  1         2  
  1         14  
41              
42 1     1   422 use Carp qw(confess);
  1         3  
  1         2112  
43              
44             has dbh => (is => 'ro');
45              
46             has cv_data => (is => 'ro', init_arg => undef, lazy_build => 1);
47             has cvprop_data => (is => 'ro', init_arg => undef, lazy_build => 1);
48             has db_data => (is => 'ro', init_arg => undef, lazy_build => 1);
49              
50             has cvterm_data => (is => 'ro', init_arg => undef, lazy_build => 1);
51             has dbxref_data => (is => 'ro', init_arg => undef, lazy_build => 1);
52              
53             has cvtermsynonyms_by_cvterm_id => (is => 'rw', init_arg => undef, lazy_build => 1);
54              
55             our @cvterm_column_names = qw(cvterm_id name cv_id dbxref_id is_obsolete is_relationshiptype);
56             our @dbxref_column_names = qw(dbxref_id db_id accession);
57              
58             sub _execute
59             {
60 29     29   48 my $self = shift;
61 29         69 my $sql = shift;
62 29         49 my $proc = shift;
63              
64 29         95 my $dbh = $self->dbh();
65              
66 29         81 my $sth = $dbh->prepare($sql);
67 29         2945 my $rv = $sth->execute();
68 29 50       126 if (!$rv) {
69 0         0 die "couldn't execute() $sql: ", $dbh->errstr(), "\n";
70             }
71              
72 29         90 while (my $ref = $sth->fetchrow_hashref() ) {
73 148         3366 $proc->($ref);
74             }
75              
76 29         339 $sth->finish();
77             }
78              
79             sub _get_cv_or_db
80             {
81 28     28   42 my $self = shift;
82 28         56 my $table_name = shift;
83              
84 28         62 my $table_id_column = "${table_name}_id";
85              
86 28         86 my %by_id = ();
87 28         43 my %by_name = ();
88              
89             my $proc = sub {
90 147     147   203 my $row_ref = shift;
91              
92 147         231 my $id = $row_ref->{$table_id_column};
93 147         220 my $name = $row_ref->{name};
94              
95 147         335 my %data = (
96             $table_id_column, $id,
97             name => $name,
98             );
99              
100 147         303 $by_id{$id} = \%data;
101 147         546 $by_name{$name} = \%data;
102              
103 28         131 };
104              
105 28         126 $self->_execute("select $table_id_column, name from $table_name", $proc);
106              
107 28         320 return \%by_id, \%by_name;
108             }
109              
110             sub _build_cv_data
111             {
112 11     11   27 my $self = shift;
113              
114 11         30 my ($cvs_by_cv_id, $cvs_by_cv_name) = $self->_get_cv_or_db('cv');
115 11         104 return { by_id => $cvs_by_cv_id, by_name => $cvs_by_cv_name };
116             }
117              
118             sub _build_cvprop_data
119             {
120 1     1   4 my $self = shift;
121              
122 1         3 my %by_cv_id = ();
123              
124             my $proc = sub {
125 1     1   5 my $row_ref = shift;
126              
127 1         3 my $cv_id = $row_ref->{cv_id};
128              
129             my %data = (
130             cv_id => $cv_id,
131             type_id => $row_ref->{type_id},
132             value => $row_ref->{value}
133 1         5 );
134              
135 1         2 push @{$by_cv_id{$cv_id}}, \%data;
  1         5  
136 1         5 };
137              
138 1         4 $self->_execute("select cv_id, type_id, value from cvprop", $proc);
139              
140 1         15 return \%by_cv_id;
141             }
142              
143             sub get_cv_by_name
144             {
145 15     15 0 34 my $self = shift;
146 15         23 my $cv_name = shift;
147              
148 15         83 return $self->cv_data()->{by_name}->{$cv_name};
149             }
150              
151             sub get_cv_names
152             {
153 2     2 0 4 my $self = shift;
154              
155 2         8 return keys %{$self->cv_data()->{by_name}};
  2         14  
156             }
157              
158             sub _build_db_data
159             {
160 17     17   34 my $self = shift;
161              
162 17         40 my ($dbs_by_db_id, $dbs_by_db_name) = $self->_get_cv_or_db('db');
163 17         96 return { by_id => $dbs_by_db_id, by_name => $dbs_by_db_name, };
164             }
165              
166             sub get_db_by_name
167             {
168 8     8 0 14 my $self = shift;
169 8         14 my $db_name = shift;
170              
171 8         32 return $self->db_data()->{by_name}->{$db_name};
172             }
173              
174             sub get_db_names
175             {
176 2     2 0 6 my $self = shift;
177              
178 2         3 return keys %{$self->db_data()->{by_name}};
  2         12  
179             }
180              
181             sub _get_by_copy
182             {
183 26     26   47 my $self = shift;
184 26         43 my $table_name = shift;
185 26         39 my $column_names_ref = shift;
186 26         69 my @column_names = @$column_names_ref;
187 26         41 my $proc = shift;
188              
189 26         72 my $dbh = $self->dbh();
190              
191 26         80 my $column_names = join ',', @column_names;
192              
193 26 50       116 $dbh->do("COPY $table_name($column_names) TO STDOUT CSV")
194             or die "failed to COPY $table_name: ", $dbh->errstr, "\n";
195              
196 26         6101 my $tsv = Text::CSV->new({sep_char => ","});
197              
198 26         3370 my $line = undef;
199              
200 26         90 while ($dbh->pg_getcopydata(\$line) > 0) {
201 308         135028 chomp $line;
202 308 50       897 if ($tsv->parse($line)) {
203 308         7296 my @fields = $tsv->fields();
204 308         2620 $proc->(\@fields);
205             } else {
206 0         0 die "couldn't parse this line: $line\n";
207             }
208             }
209             }
210              
211             sub _get_cvtermsynonyms
212             {
213 0     0   0 my $self = shift;
214              
215 0         0 my $dbh = $self->dbh();
216              
217 0         0 my @column_names = qw(cvtermsynonym_id cvterm_id synonym type_id);
218              
219 0         0 my %by_cvterm_id = ();
220              
221             my $proc = sub {
222 0     0   0 my $fields_ref = shift;
223 0         0 my @fields = @$fields_ref;
224 0         0 my ($cvtermsynonym_id, $cvterm_id, $synonym, $type_id) = @fields;
225 0         0 $by_cvterm_id{$cvterm_id} = \@fields;
226 0         0 };
227              
228 0         0 $self->_get_by_copy('cvtermsynonym', \@column_names, $proc);
229              
230 0         0 return \%by_cvterm_id
231             }
232              
233             sub _make_term
234             {
235 105     105   163 my $self = shift;
236 105         194 my $cvterm_data = shift;
237 105         156 my $dbxref_data = shift;
238              
239 105         201 my $dbxref_id = $cvterm_data->[3];
240              
241 105         183 my $by_dbxref_id = $dbxref_data->{by_dbxref_id};
242 105         204 my $termid = $by_dbxref_id->{$dbxref_id}->{termid};
243              
244 105         770 return bless {
245             id => $termid,
246             cvterm_id => $cvterm_data->[0],
247             name => $cvterm_data->[1],
248             cv_id => $cvterm_data->[2],
249             dbxref_id => $dbxref_id,
250             is_obsolete => $cvterm_data->[4],
251             is_relationshiptype => $cvterm_data->[5],
252             }, 'PomBase::Chobo::OntologyTerm';
253             }
254              
255             sub _build_cvterm_data
256             {
257 11     11   24 my $self = shift;
258              
259 11         20 my %by_cvterm_id = ();
260 11         28 my %by_cv_id = ();
261 11         22 my %by_termid = ();
262              
263 11         50 my $dbxref_data = $self->dbxref_data();
264              
265             my $proc = sub {
266 105     105   169 my $fields_ref = shift;
267              
268 105         263 my $term = $self->_make_term($fields_ref, $dbxref_data);
269              
270 105         400 $by_cvterm_id{$term->cvterm_id()} = $term;
271 105         384 $by_cv_id{$term->cv_id()}->{$term->name()} = $term;
272 105         508 $by_termid{$term->id()} = $term;
273 11         68 };
274              
275 11         53 $self->_get_by_copy('cvterm', \@cvterm_column_names, $proc);
276              
277             return {
278 11         488 by_cvterm_id => \%by_cvterm_id,
279             by_cv_id => \%by_cv_id,
280             by_termid => \%by_termid,
281             };
282             }
283              
284             sub get_cvterm_by_cvterm_id
285             {
286 0     0 0 0 my $self = shift;
287              
288 0         0 return $self->cvterm_data()->{by_cvterm_id};
289             }
290              
291             sub get_cvterms_by_cv_id
292             {
293 7     7 0 18 my $self = shift;
294 7         13 my $cv_id = shift;
295              
296 7 50       21 if (!defined $cv_id) {
297 0         0 confess "undefined cv_id passed to get_cvterms_by_cv_id()";
298             }
299              
300 7         45 return $self->cvterm_data()->{by_cv_id}->{$cv_id};
301             }
302              
303             sub get_cvterm_by_termid
304             {
305 23     23 0 41 my $self = shift;
306 23         40 my $termid = shift;
307              
308 23         101 return $self->cvterm_data()->{by_termid}->{$termid};
309             }
310              
311             sub get_all_cvterms
312             {
313 2     2 0 4 my $self = shift;
314              
315 2         3 return values %{$self->cvterm_data()->{by_termid}};
  2         13  
316             }
317              
318             sub get_cvterm_by_name
319             {
320 3     3 0 11 my $self = shift;
321 3         8 my $cv_name = shift;
322 3         8 my $cvterm_name = shift;
323              
324 3         13 my $cv = $self->get_cv_by_name($cv_name);
325              
326 3         21 return $self->get_cvterms_by_cv_id($cv->{cv_id})->{$cvterm_name};
327             }
328              
329             sub get_cvprop_values
330             {
331 1     1 0 35242 my $self = shift;
332 1         4 my $cv_name = shift;
333 1         2 my $prop_type_name = shift;
334              
335 1         5 my $cv = $self->get_cv_by_name($cv_name);
336 1         10 my $cvprops = $self->cvprop_data()->{$cv->{cv_id}};
337 1         4 my $prop_type = $self->get_cvterm_by_name('cv_property_type', $prop_type_name);
338              
339             return map {
340             $_->{value}
341 1         6 }
342             grep {
343             $_->{type_id} == $prop_type->{cvterm_id}
344 1   50     4 } @{$cvprops // []};
  1         6  
  1         6  
345             }
346              
347             sub get_all_termids
348             {
349 8     8 0 16 my $self = shift;
350              
351 8         10 return keys %{$self->dbxref_data()->{by_termid}};
  8         34  
352             }
353              
354             sub get_dbxref_by_termid
355             {
356 15     15 0 27 my $self = shift;
357 15         20 my $termid = shift;
358              
359 15         50 return $self->dbxref_data()->{by_termid}->{$termid};
360             }
361              
362             sub _build_dbxref_data
363             {
364 15     15   33 my $self = shift;
365              
366 15         46 my $dbh = $self->dbh();
367              
368 15         54 my $db_data = $self->db_data();
369              
370 15         25 my %by_dbxref_id = ();
371 15         32 my %by_termid = ();
372 15         23 my %by_db_name = ();
373              
374             my $proc = sub {
375 203     203   326 my $fields_ref = shift;
376 203         461 my @fields = @$fields_ref;
377 203         407 my ($dbxref_id, $db_id, $accession, $version) = @fields;
378              
379 203         776 my %data = (dbxref_id => $dbxref_id,
380             db_id => $db_id,
381             accession => $accession,
382             version => $version);
383              
384 203         452 my $db_name = $db_data->{by_id}->{$db_id}->{name};
385 203 50       441 if (!defined $db_name) {
386 0         0 die "no db name for db $db_id";
387             }
388              
389 203         279 my $termid;
390              
391 203 50       384 if ($db_name eq '_global') {
392 0         0 $termid = $accession;
393             } else {
394 203         516 $termid = "$db_name:$accession";
395             }
396              
397 203         349 $data{termid} = $termid;
398              
399 203         429 $by_dbxref_id{$dbxref_id} = \%data;
400 203         415 $by_termid{$termid} = \%data;
401 203         974 $by_db_name{$db_name}->{$termid} = \%data;
402 15         131 };
403              
404 15         54 $self->_get_by_copy('dbxref', \@dbxref_column_names, $proc);
405              
406             return {
407 15         685 by_dbxref_id => \%by_dbxref_id,
408             by_termid => \%by_termid,
409             by_db_name => \%by_db_name,
410             };
411             }
412              
413             sub _build_cvtermsynonyms_by_cvterm_id
414             {
415 0     0     my $self = shift;
416              
417 0           return $self->_get_cvtermsynonyms();
418             }
419              
420             sub get_cvtermsynonyms_by_cvterm_id
421             {
422 0     0 0   my $self = shift;
423 0           my $cvterm_id = shift;
424              
425 0           return $self->cvtermsynonyms_by_cvterm_id()->{$cvterm_id};
426             }
427              
428             1;