[Bio] / Sprout / TargetCriterionQuery.pm Repository:
ViewVC logotype

Annotation of /Sprout/TargetCriterionQuery.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (view) (download) (as text)

1 : parrello 1.1 #!/usr/bin/perl -w
2 :    
3 :     #
4 :     # Copyright (c) 2003-2006 University of Chicago and Fellowship
5 :     # for Interpretations of Genomes. All Rights Reserved.
6 :     #
7 :     # This file is part of the SEED Toolkit.
8 :     #
9 :     # The SEED Toolkit is free software. You can redistribute
10 :     # it and/or modify it under the terms of the SEED Toolkit
11 :     # Public License.
12 :     #
13 :     # You should have received a copy of the SEED Toolkit Public License
14 :     # along with this program; if not write to the University of Chicago
15 :     # at info@ci.uchicago.edu or the Fellowship for Interpretation of
16 :     # Genomes at veronika@thefig.info or download a copy from
17 :     # http://www.theseed.org/LICENSE.TXT.
18 :     #
19 :    
20 :     package TargetCriterionQuery;
21 :    
22 :     use strict;
23 :     use Tracer;
24 :     use Sprout;
25 :     use base qw(TargetCriterion);
26 :    
27 :     =head1 Code Match Target Search Criterion Object
28 :    
29 :     =head2 Introduction
30 :    
31 :     This is a query-based search criterion object. It serves as the base class for most
32 :     search criterion that revolve around the use of a single database field. The constructor
33 :     specifies a field name followed by a list of table names. The table name list must
34 :     always begin with either C<Feature> or C<Genome>. The subclasses will need to override
35 :     most methods, but this object comes with some built-in utilities for manipulating the
36 :     path and field name that the various subclasses will find essential.
37 :    
38 :     This object has the following fields in addition to the ones in the base class.
39 :    
40 :     =over 4
41 :    
42 :     =item path
43 :    
44 :     Reference to a list of the objects in the join path required for this query.
45 :    
46 :     =item field
47 :    
48 :     Name of the field containing the data relevant to the query.
49 :    
50 :     =item keyTable
51 :    
52 :     Name of the object containing the relevant field.
53 :    
54 :     =item basic
55 :    
56 :     TRUE if the field is in the B<Genome> or B<Feature> tables, else FALSE.
57 :    
58 :     =item erdbType
59 :    
60 :     [[ERDBTypePm]] object describing the data type of the field.
61 :    
62 :     =item sanity
63 :    
64 :     TRUE if the field is feature-based, else FALSE.
65 :    
66 :     =back
67 :    
68 :     =head3 new
69 :    
70 :     my $tc = TargetCriterionQuery->new($rhelp, $options, $field => @path);
71 :    
72 :     Construct a new TargetCriterionQuery object. The following parameters are
73 :     expected.
74 :    
75 :     =over 4
76 :    
77 :     =item rhelp
78 :    
79 :     [[ResultHelperPm]] object for the active search.
80 :    
81 :     =item options
82 :    
83 :     Reference to a hash of constructor options. These match the options on the constructor
84 :     for the base class.
85 :    
86 :     =item field
87 :    
88 :     Name of the relevant database field.
89 :    
90 :     =item path
91 :    
92 :     List of entities and relationships forming a path from the C<Genome> or C<Feature> table
93 :     to the table containing the database field.
94 :    
95 :     =back
96 :    
97 :     =cut
98 :    
99 :     sub new {
100 :     # Get the parameters.
101 :     my ($class, $rhelp, $options, $field, @path) = @_;
102 :     # Construct the underlying object.
103 :     my $retVal = TargetCriterion::new($class, $rhelp, %$options);
104 :     # Compute the keytable. It's the last table in the path.
105 :     my $keyTable = $path[$#path];
106 :     # Compute the path. It is either an empty list or the incoming path.
107 :     my @realPath = ();
108 :     if (scalar(@path) > 1) {
109 :     push @realPath, @path;
110 :     }
111 :     # Save the custom fields.
112 :     $retVal->{path} = \@realPath;
113 :     $retVal->{field} = $field;
114 :     $retVal->{keyTable} = $keyTable;
115 :     $retVal->{basic} = scalar(grep { $_ eq $keyTable } qw(Genome Feature));
116 :     $retVal->{sanity} = ($path[0] eq 'Feature');
117 :     # Compute the ERDB type of the field.
118 :     my $sprout = $rhelp->DB();
119 :     $retVal->{erdbType} = $sprout->FieldType($field, $keyTable);
120 :     # Return the object.
121 :     return $retVal;
122 :     }
123 :    
124 :     =head3 Utility Methods
125 :    
126 :     =head3 RelevantField
127 :    
128 :     my $fieldSpec = $tc->RelevantField();
129 :    
130 :     Return the name, in ERDB format, of the field relevant to this query.
131 :    
132 :     =over 4
133 :    
134 :     =item RETURN
135 :    
136 :     Returns a formatted ERDB-style name for the target field.
137 :    
138 :     =back
139 :    
140 :     =cut
141 :    
142 :     sub RelevantField {
143 :     # Get the parameters.
144 :     my ($self) = @_;
145 :     # Get the key table name.
146 :     my $name = $self->{keyTable};
147 :     # Form the field name.
148 :     my $retVal = "$name($self->{field})";
149 :     # Return the result.
150 :     return $retVal;
151 :     }
152 :    
153 :     =head3 JoinList
154 :    
155 :     my $joins = $tc->JoinList();
156 :    
157 :     Return the join list for this criterion. The join list will be a
158 :     reference to an empty list (indicating the field is in the B<Genome> or
159 :     B<Feature> table) or a reference to a list that specifies the join path
160 :     to get the to table containing the relevant field.
161 :    
162 :     =cut
163 :    
164 :     sub JoinList {
165 :     # Get the parameters.
166 :     my ($self) = @_;
167 :     # Return the result.
168 :     return $self->{path};
169 :     }
170 :    
171 :     =head3 ReadDatabaseValues
172 :    
173 :     my @values = $tc->ReadDatabaseValues($fid);
174 :    
175 :     Read this field's values from the database. This method is called when we
176 :     need a field at search time and it's not a basic field (that is, it isn't
177 :     in the Feature or Genome tables) or when we need a field at runtime.
178 :    
179 :     =over 4
180 :    
181 :     =item fid
182 :    
183 :     ID of the current feature.
184 :    
185 :     =item RETURN
186 :    
187 :     Returns a list of the values for the given field.
188 :    
189 :     =back
190 :    
191 :     =cut
192 :    
193 :     sub ReadDatabaseValues {
194 :     # Get the parameters.
195 :     my ($self, $fid) = @_;
196 :     # Declare the return variable.
197 :     my @retVal;
198 :     # Get the Sprout database.
199 :     my $sprout = $self->DB();
200 :     # Get the key table name.
201 :     my $keyTable = $self->{keyTable};
202 :     # Get the field name.
203 :     my $field = $self->RelevantField();
204 :     # Check to see if this is a basic field.
205 :     if ($self->{basic}) {
206 :     # Yes. Determine the appropriate ID (either Genome or Feature).
207 :     my $thingID = ($keyTable eq 'Genome' ? FIGRules::ParseFeatureID($fid) : $fid);
208 :     # Do the GetFlat.
209 :     @retVal = $sprout->GetFlat($keyTable, "$keyTable(id) = ?", [$thingID], $field);
210 :     } else {
211 :     # Here the field is in a table at the end of a path. Get the path and yank off
212 :     # the starting table.
213 :     my ($startTable, @path) = @{$self->JoinList()};
214 :     # If the start table is Genome, we simply use the HasFeature table to get us to
215 :     # the genome from the feature.
216 :     if ($startTable eq 'Genome') {
217 :     @retVal = $sprout->GetFlat(['HasFeature', @path], "HasFeature(to-link) = ?",
218 :     [$fid], $field);
219 :     } else {
220 :     # Here we're starting from the feature table. Determine which field in the
221 :     # starting relationship is the feature field.
222 :     my ($from, $to) = $sprout->GetRelationshipEntities($path[0]);
223 :     my $linkName = ($from eq 'Feature' ? 'from-link' : 'to-link');
224 :     # Build the query.
225 :     @retVal = $sprout->GetFlat(\@path, "$path[0]($linkName) = ?", [$fid],
226 :     $field);
227 :     }
228 :     }
229 :     # Return the value list.
230 :     return @retVal;
231 :     }
232 :    
233 :     =head3 FormatValueList
234 :    
235 :     my $html = $self->FormatValueList(\@values);
236 :    
237 :     Format a list of values for the current field. The values are converted
238 :     to HTML using the method appropriate to the field type and then joined
239 :     together with commas. If the value is a singleton no commas will appear.
240 :    
241 :     =over 4
242 :    
243 :     =item values
244 :    
245 :     Reference to a list of values to format.
246 :    
247 :     =item RETURN
248 :    
249 :     Returns an HTML string with the best possible representation for the field values.
250 :    
251 :     =back
252 :    
253 :     =cut
254 :    
255 :     sub FormatValueList {
256 :     # Get the parameters.
257 :     my ($self, $values) = @_;
258 :     # Get the ERDB type object for this field.
259 :     my $typeData = $self->{erdbType};
260 :     # Use it to convert the values to HTML.
261 :     my @elements = map { $typeData->html($_) } @$values;
262 :     # String them together.
263 :     my $retVal = join(", ", @elements);
264 :     # Return the result.
265 :     return $retVal;
266 :     }
267 :    
268 :     =head2 Virtual Methods
269 :    
270 :     =head3 GetValueData
271 :    
272 :     my $value = $tc->GetValueData($feature);
273 :    
274 :     Return the value data from the specified feature that is relevant to this
275 :     criterion. This method is called when the object cache is empty and the
276 :     value is needed in order to call L</CheckValue>.
277 :    
278 :     =over 4
279 :    
280 :     =item feature
281 :    
282 :     An [[ERDBObjectPm]] describing the current feature.
283 :    
284 :     =item RETURN
285 :    
286 :     Returns a scalar containing the value used to determine whether or not the specified
287 :     feature will match a criterion of this type. The object can be a list reference, a hash
288 :     reference, or a blessed object, so long as the virtual L</PutExtraColumns> and
289 :     L</CheckValue> methods understand it.
290 :    
291 :     =back
292 :    
293 :     =cut
294 :    
295 :     sub GetValueData {
296 :     # Get the parameters.
297 :     my ($self, $feature) = @_;
298 :     # Declare the return variable.
299 :     my $retVal;
300 :     # Get the field name.
301 :     my $field = $self->RelevantField();
302 :     # Is this a basic field?
303 :     if ($self->{basic}) {
304 :     # Yes. Pull it out of the feature object.
305 :     $retVal = [ $feature->Value($field) ];
306 :     } else {
307 :     # Here we have to read the value from a table at the end of a path. We
308 :     # begin by getting the current feature ID.
309 :     my $fid = $feature->PrimaryValue('Feature(id)');
310 :     # Ask for the field's values.
311 :     $retVal = [ $self->ReadDatabaseValues($fid) ];
312 :     }
313 :     # Return the result.
314 :     return $retVal;
315 :     }
316 :    
317 :     =head3 Sane
318 :    
319 :     my $flag = $tc->Sane($parms);
320 :    
321 :     Return TRUE if this is a sane criterion, else FALSE. Every search must have at least one
322 :     sane criterion in order to be valid.
323 :    
324 :     =over 4
325 :    
326 :     =item parms (optional)
327 :    
328 :     The Criterion Parameter Object for the current query.
329 :    
330 :     =item RETURN
331 :    
332 :     Returns TRUE if this query returns a relatively limited result set and uses SQL,
333 :     else FALSE. If you do not override this method, it returns TRUE for feature-based
334 :     criteria and FALSE for genome-based criteria.
335 :    
336 :     =back
337 :    
338 :     =cut
339 :    
340 :     sub Sane {
341 :     my ($self, $parms) = @_;
342 :     return $self->{sanity};
343 :     }
344 :    
345 :     =head3 colName
346 :    
347 :     my $name = $tc->colName();
348 :    
349 :     Return the column name for this criterion. Normally, the column name is
350 :     the same as the label. In some cases, however, we have criterion types
351 :     that involve built-in columns. For these, this method should be
352 :     overridden so that it returns the built-in column's name.
353 :    
354 :     =cut
355 :    
356 :     sub colName {
357 :     # Get the parameters.
358 :     my ($self) = @_;
359 :     # Get our field's name.
360 :     my $field = $self->RelevantField();
361 :     # Ask the result helper if we're built-in. If we aren't, we return our own name.
362 :     my $retVal = RHFeatures::FieldMap($field) || $self->name();
363 :     # Return the result.
364 :     return $retVal;
365 :     }
366 :    
367 :    
368 :     =head3 DownloadType
369 :    
370 :     my $dlType = $tc->DownloadType();
371 :    
372 :     Return the download type of this criterion's data column. This will
373 :     usually be C<list>, C<num>, or C<text>.
374 :    
375 :     =cut
376 :    
377 :     sub DownloadType {
378 :     # Get the parameters.
379 :     my ($self) = @_;
380 :     # Get the database.
381 :     my $sprout = $self->DB();
382 :     # Get our field's name.
383 :     my $field = $self->RelevantField();
384 :     # If we are keying off a secondary field, or a non-basic field, it's
385 :     # automatically a list. Otherwise, it's numeric or a string.
386 :     my $retVal;
387 :     if (! $self->{basic} || $sprout->IsSecondary($field)) {
388 :     $retVal = 'list';
389 :     } else {
390 :     # Get the field type.
391 :     my $erdbTypeObject = $self->{erdbType};
392 :     if ($erdbTypeObject->numeric()) {
393 :     $retVal = 'num';
394 :     } else {
395 :     $retVal = 'text';
396 :     }
397 :     }
398 :     # Return the result.
399 :     return $retVal;
400 :     }
401 :    
402 :     =head3 CacheValue
403 :    
404 :     my $value = $tc->CacheValue($feature);
405 :    
406 :     Return the value to cache for this criterion with respect to the specified
407 :     feature. Normally, this will be an HTML displayable version of the
408 :     appropriate value. If the value is immediate;y available, it is
409 :     returned; however, if the value is not available at the current time, a
410 :     runtime-value request is returned in its place.
411 :    
412 :     =over 4
413 :    
414 :     =item feature
415 :    
416 :     [[ERDBObjectPm]] object containing the data for the current feature.
417 :    
418 :     =item RETURN
419 :    
420 :     Returns the value that should be put in the search result cache file for
421 :     this column.
422 :    
423 :     =back
424 :    
425 :     =cut
426 :    
427 :     sub CacheValue {
428 :     # Get the parameters.
429 :     my ($self, $feature) = @_;
430 :     # Declare the return variable.
431 :     my $retVal;
432 :     # We need to determine if we already have the value or not. First, we check
433 :     # the cache.
434 :     if (defined $self->{cache}) {
435 :     # Yes. Format it as HTML.
436 :     $retVal = $self->FormatValueList($self->{cache});
437 :     } else {
438 :     # It's not in the cache, but if it's already in the feature record, we can
439 :     # get it cheaply.
440 :     my $field = $self->RelevantField();
441 :     if ($feature->HasField($field)) {
442 :     $retVal = $self->FormatValueList([ $feature->Value($field) ]);
443 :     } else {
444 :     # Here we have to put it off until runtime.
445 :     my $name = $self->name();
446 :     my $fid = $feature->PrimaryValue('Feature(id)');
447 :     $retVal = "%%$name=$fid";
448 :     }
449 :     }
450 :     # Return the result.
451 :     return $retVal;
452 :     }
453 :    
454 :    
455 :     =head3 RunTimeValue
456 :    
457 :     my $runTimeValue = $tc->RunTimeValue($runTimeKey);
458 :    
459 :     Return the run-time value for this column using the specified key. The key
460 :     in this case will be the feature ID. The feature ID continas the genome ID
461 :     embedded within it.
462 :    
463 :     The way we compute the run-time value depends on where the value can be found.
464 :     If it's in the Feature or Genome objects, we simply read it using B<GetFlat>.
465 :     Otherwise, we
466 :    
467 :     =over 4
468 :    
469 :     =item runTimeKey
470 :    
471 :     Key value placed in the search result cache when the need for the desired
472 :     value was determined during search processing. This will be the feature
473 :     ID.
474 :    
475 :     =item RETURN
476 :    
477 :     Returns the actual value to be used for the specified column.
478 :    
479 :     =back
480 :    
481 :     =cut
482 :    
483 :     sub RunTimeValue {
484 :     # Get the parameters.
485 :     my ($self, $runTimeKey) = @_;
486 :     # Read the values from the database. Note that the run-time key in this case
487 :     # is a feature ID.
488 :     my @values = $self->ReadDatabaseValues($runTimeKey);
489 :     # Format the values for HTML display.
490 :     my $retVal = $self->FormatValueList(\@values);
491 :     # Return the result.
492 :     return $retVal;
493 :     }
494 :    
495 :    
496 :    
497 :     1;

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3