File Coverage

blib/lib/Bio/ConnectDots/ConnectorSet.pm
Criterion Covered Total %
statement 24 140 17.1
branch 4 68 5.8
condition 0 26 0.0
subroutine 7 19 36.8
pod 0 10 0.0
total 35 263 13.3


line stmt bran cond sub pod time code
1             package Bio::ConnectDots::ConnectorSet;
2 2     2   2395 use vars qw(@ISA @AUTO_ATTRIBUTES @OTHER_ATTRIBUTES %SYNONYMS);
  2         6  
  2         305  
3 2     2   157 use strict;
  2         3  
  2         74  
4 2     2   5875 use Bio::ConnectDots::Util;
  2         7  
  2         543  
5 2     2   17 use Bio::ConnectDots::Connector;
  2         3  
  2         43  
6 2     2   2078 use Bio::ConnectDots::DB::ConnectorSet;
  2         8  
  2         168  
7 2     2   15 use Class::AutoClass;
  2         7  
  2         5873  
8             @ISA = qw(Class::AutoClass); # AutoClass must be first!!
9              
10             @AUTO_ATTRIBUTES=qw(name file cs_version ftp ftp_files saved_file db db_id
11             label2dotset label2labelid dots_hash input_fh
12             _current _instances label_annotations source_version source_date download_date comment);
13              
14             @OTHER_ATTRIBUTES=qw(dotsets labels);
15             %SYNONYMS=();
16             Class::AutoClass::declare(__PACKAGE__);
17              
18             sub _init_self {
19 3     3   2726 my($self,$class,$args)=@_;
20 3 50       13 return unless $class eq __PACKAGE__; # to prevent subclasses from re-running this
21 3 50       88 return if $self->db_id; # already fetched
22 3         41 my $module=$args->module;
23 3 50       106 if ($module) { # dynamically load subclass
24 0         0 my $module_file="Bio/ConnectDots/ConnectorSet/$module.pm";
25 0         0 require $module_file;
26 0         0 bless $self,ref($self)."::$module";
27             }
28 3 50       79 return unless $self->db;
29 0   0       my $label2dotset=$self->label2dotset || $self->label2dotset({});
30 0   0       my $label2labelid=$self->label2labelid || $self->label2labelid({});
31 0           my $saved=Bio::ConnectDots::DB::ConnectorSet->get($self);
32 0           my @newlabels;
33 0 0         if ($saved) {
34 0           $self->db_id($saved->db_id);
35 0           $self->saved_file($saved->file); # so application can catch duplicate loads
36             # compare in-memory vs. saved dotsets
37 0           my $saved_l2d=$saved->label2dotset;
38 0           my $saved_l2i=$saved->label2labelid;
39 0           while(my($label,$dotset)=each %$label2dotset) {
40 0           my $saved_dotset=$saved_l2d->{$label};
41 0 0         push(@newlabels,$label), next unless $saved_dotset;
42 0 0         $self->throw("In-memory and saved ConnectorSets use label $label for two different DotSets: ".$dotset->name." vs. ".$saved_dotset->name) unless $dotset->name eq $saved_dotset->name;
43 0           $dotset->db_id($saved_dotset->db_id);
44 0           $label2labelid->{$label}=$saved_l2i->{$label};
45             }
46             } else { # everything is new
47 0           @newlabels=$self->labels;
48             }
49 0           Bio::ConnectDots::DB::ConnectorSet->put($self,@newlabels); # store new information
50              
51             # open file if provided
52 0 0         $self->open_file if $self->file;
53             }
54             sub instances {
55 0     0 0   my $self= shift;
56 0   0       my $instances=$self->_instances || $self->_instances([]);
57 0 0         push(@$instances,@_) if @_;
58 0 0         wantarray? @$instances: $instances;
59             }
60             # normalize parameters to hash -- create DotSet objects
61             sub dotsets {
62 0     0 0   my $self=shift;
63 0   0       my $label2dotset=$self->label2dotset || $self->label2dotset({});
64 0 0         if (@_) {
65 0           my @dotsets=_flatten(@_);
66 0           my $name2dotset={};
67 0           for my $dotset (@dotsets) {
68 0 0         unless ('HASH' eq ref $dotset) {
69 0           $dotset=$self->_fix_dotset($dotset,$name2dotset);
70 0           my $label=$dotset->name;
71 0 0         $self->throw("Two DotSets have same label: $label") if $label2dotset->{$label};
72 0           $label2dotset->{$label}=$dotset;
73             } else { # hash: label=>name or DotSet
74 0           my $hash=$dotset;
75 0           while(my($label,$dotset)=each %$hash) {
76 0           $dotset=$self->_fix_dotset($dotset,$name2dotset);
77 0 0         $self->throw("Two DotSets have same label: $label") if $label2dotset->{$label};
78 0           $label2dotset->{$label}=$dotset;
79             }
80             }
81             }
82             }
83 0           my @dotsets=uniq(values %$label2dotset);
84 0 0         wantarray? @dotsets: \@dotsets;
85             }
86             sub _fix_dotset {
87 0     0     my($self,$dotset,$name2dotset)=@_;
88 0 0 0       $self->throw("Unrecognized parameter to dotsets: $dotset")
89             unless !ref $dotset || UNIVERSAL::isa($dotset,'Bio::ConnectDots::DotSet');
90 0 0         if (!ref $dotset) { # scalar: should be DotSet name
91 0           my $name=$dotset;
92 0   0       $dotset=$name2dotset->{$name} ||
93             ($name2dotset->{$name}=new Bio::ConnectDots::DotSet(-name=>$name,-db=>$self->db));
94             } else { # already DotSet object -- just test for duplicates
95 0           my $name=$dotset->name;
96 0 0 0       $self->throw("Two DotSets have same name")
97             if $name2dotset->{$name} && $name2dotset->{$name} != $dotset;
98 0           $name2dotset->{$name}=$dotset;
99             }
100 0           $dotset;
101             }
102             sub labels {
103 0     0 0   my $self=shift;
104 0           my @labels=_flatten(@_);
105 0           my @results;
106 0 0         if (@labels) {
107 0           my $label2dotset=$self->label2dotset;
108 0           @results=grep {exists $label2dotset->{$_}} @labels;
  0            
109             } else {
110 0           @results=keys %{$self->label2dotset};
  0            
111             }
112 0 0         wantarray? @results: \@results;
113             }
114             sub put {
115 0     0 0   my($self,$connector)=@_;
116 0           $self->instances($connector);
117 0           $connector;
118             }
119             sub open_file {
120 0     0 0   my($self,$file)=@_;
121 0 0         $file or $file=$self->file;
122 0 0         $self->throw("Attempting to open file, but file is not set") unless $file;
123 0           my $input_fh;
124 0 0         open($input_fh,"< $file") or $self->throw("open of $file failed: $!");
125 0           $self->input_fh($input_fh);
126             }
127             sub parse_file {
128 0     0 0   my $self=shift;
129 0 0         unless ($self->input_fh) {
130 0 0         my $file=shift or $self->file;
131 0           $self->throw("Cannot parse file: no file provided");
132 0           $self->open_file($file);
133             }
134 0           while ($self->parse_entry) {
135 0           my $connector=new Bio::ConnectDots::Connector(-connectorset=>$self);
136 0           $self->put($connector);
137 0           $self->dots_hash(undef);
138             }
139             }
140             sub load_file {
141 0     0 0   my($self,$load_save,$load_chunksize)=@_;
142 0           my $db=$self->db;
143 0 0         $self->throw("Cannot load file: ConnectorSet has no database") unless $db;
144 0 0         $self->throw("Cannot load file: database not connected") unless $db->is_connected;
145 0 0         $self->throw("Cannot load file: database does not exist") unless $db->exists;
146 0 0         unless ($self->input_fh) {
147 0 0         my $file=shift or $self->file;
148 0           $self->throw("Cannot load file: no file provided");
149 0           $self->open_file($file);
150             }
151 0           my $connectorset_id=$self->db_id;
152 0           my $label2dotset=$self->label2dotset;
153 0           my $label2labelid=$self->label2labelid;
154 0           $db->load_init($self->name,$load_save,$load_chunksize);
155 0           my $connector_id=1;
156 0           while ($self->parse_entry) {
157 0           my $dots_hash=$self->dots_hash;
158 0           while(my($label,$ids)=each %$dots_hash) {
159 0           my $dotset_id=$label2dotset->{$label}->db_id;
160 0           my $label_id=$label2labelid->{$label};
161 0           for my $id (@$ids) {
162 0           $db->load_row($connector_id,$connectorset_id,$id,$dotset_id,$label_id);
163             }
164             }
165 0           $connector_id++;
166 0           $self->dots_hash(undef);
167             }
168 0           $db->load_finish;
169             }
170             sub parse_entry {
171 0     0 0   my($self)=@_;
172 0           $self->throw("parse_enrty() Not implemented: must be implemented in subclass");
173             }
174             sub have_dots {
175 0     0 0   my $dots_hash=$_[0]->dots_hash;
176 0 0         $dots_hash and %$dots_hash? 1: undef;
    0          
177             }
178             sub put_dot {
179 0     0 0   my($self,$label,$value)=@_;
180 0 0         return unless length($value)>0; # skip empty strings
181 0   0       my $dots_hash=$self->dots_hash || $self->dots_hash({});
182 0   0       my $list=$dots_hash->{$label} || ($dots_hash->{$label}=[]);
183 0           push(@$list,$value);
184 0           $list;
185             }
186              
187 0 0   0     sub _flatten {map {'ARRAY' eq ref $_? @$_: $_} @_;}
  0            
188              
189             1;
190              
191             __END__