[Bio] / FigKernelPackages / RemoteCustomAttributes.pm Repository:
ViewVC logotype

Annotation of /FigKernelPackages/RemoteCustomAttributes.pm

Parent Directory Parent Directory | Revision Log Revision Log


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

1 : parrello 1.1 #!/usr/bin/perl -w
2 :    
3 :     package RemoteCustomAttributes;
4 :    
5 :     use strict;
6 :     use Tracer;
7 :     use PageBuilder;
8 :     use Frontier::Client;
9 :    
10 :     =head1 Remote Custom Attribute Manager
11 :    
12 :     =head2 Introduction
13 :    
14 :     This package looks like a limited version of the B<CustomAttributes> object, but
15 :     it gets the data from a remote server using the Frontier XML interface. The
16 :     methods supported are the four FIG replacement methods of the custom attributes object.
17 :    
18 :     =head2 Public Methods
19 :    
20 :     =head3 new
21 :    
22 : parrello 1.8 my $rca = RemoteCustomAttributes->new($url);
23 : parrello 1.1
24 :     Construct a new RemoteCustomAttributes object served by the script at the
25 :     specified URL.
26 :    
27 :     =cut
28 :    
29 :     sub new {
30 :     # Get the parameters.
31 :     my ($class, $url) = @_;
32 :     # Create the rca object.
33 :     my $retVal = {
34 :     proxy => Frontier::Client->new(url => $url)
35 :     };
36 :     # Bless and return it.
37 :     bless $retVal, $class;
38 :     return $retVal;
39 :     }
40 :    
41 :     =head3 GetAttributes
42 :    
43 : parrello 1.8 my @attributeList = $attrDB->GetAttributes($objectID, $key, @valuePatterns);
44 : parrello 1.1
45 :     In the database, attribute values are sectioned into pieces using a splitter
46 :     value specified in the constructor (L</new>). This is not a requirement of
47 :     the attribute system as a whole, merely a convenience for the purpose of
48 :     these methods. If you are using the static method calls instead of the
49 :     object-based calls, the splitter will always be the default value of
50 :     double colons (C<::>). If a value has multiple sections, each section
51 :     is matched against the correspond criterion in the I<@valuePatterns> list.
52 :    
53 :     This method returns a series of tuples that match the specified criteria. Each tuple
54 :     will contain an object ID, a key, and one or more values. The parameters to this
55 :     method therefore correspond structurally to the values expected in each tuple.
56 :    
57 :     my @attributeList = GetAttributes('fig|100226.1.peg.1004', 'structure%', 1, 2);
58 :    
59 :     would return something like
60 :    
61 :     ['fig}100226.1.peg.1004', 'structure', 1, 2]
62 :     ['fig}100226.1.peg.1004', 'structure1', 1, 2]
63 :     ['fig}100226.1.peg.1004', 'structure2', 1, 2]
64 :     ['fig}100226.1.peg.1004', 'structureA', 1, 2]
65 :    
66 :     Use of C<undef> in any position acts as a wild card (all values). In addition,
67 :     the I<$key> and I<@valuePatterns> parameters can contain SQL pattern characters: C<%>, which
68 :     matches any sequence of characters, and C<_>, which matches any single character.
69 :     (You can use an escape sequence C<\%> or C<\_> to match an actual percent sign or
70 :     underscore.)
71 :    
72 :     In addition to values in multiple sections, a single attribute key can have multiple
73 :     values, so even
74 :    
75 :     my @attributeList = GetAttributes($peg, 'virulent');
76 :    
77 :     which has no wildcard in the key or the object ID, may return multiple tuples.
78 :    
79 :     For reasons of backward compatability, we examine the structure of the object ID to
80 :     determine the entity type. In that case the only two types allowed are C<Genome> and
81 :     C<Feature>. An alternative method is to use a list reference, with the list consisting
82 :     of an entity type name and the actual ID. Thus, the above example could equivalently
83 :     be written as
84 :    
85 :     my @attributeList = GetAttributes([Feature => $peg], 'virulent');
86 :    
87 :     The list-reference approach allows us to add attributes to other entity types in
88 :     the future. Doing so, however, will require modifying the L</Refresh> method and
89 :     updated the database design XML.
90 :    
91 :     The list-reference approach also allows for a more fault-tolerant approach to
92 :     getting all objects with a particular attribute.
93 :    
94 :     my @attributeList = GetAttributes([Feature => undef], 'virulent');
95 :    
96 :     will only return feature attributes, while
97 :    
98 :     my @attributeList = GetAttributes(undef, 'virulent');
99 :    
100 :     could at some point in the future get you attributes for genomes or even subsystems
101 :     as well as features.
102 :    
103 :     =over 4
104 :    
105 :     =item objectID
106 :    
107 :     ID of the genome or feature whose attributes are desired. In general, an ID that
108 :     starts with C<fig|> is treated as a feature ID, and an ID that is all digits with a
109 :     single period is treated as a genome ID. For other entity types, use a list reference; in
110 :     this case the first list element is the entity type and the second is the ID. A value of
111 :     C<undef> here will match all objects.
112 :    
113 :     =item key
114 :    
115 :     Attribute key name. Since attributes are stored as fields in the database with a
116 :     field name equal to the key name, it is very fast to find a list of all the
117 :     matching keys. Each key's values require a separate query, however, which may
118 :     be a performance problem if the pattern matches a lot of keys. Wild cards are
119 :     acceptable here, and a value of C<undef> will match all attribute keys.
120 :    
121 :     =item valuePatterns
122 :    
123 :     List of the desired attribute values, section by section. If C<undef>
124 :     is specified, all values in that section will match.
125 :    
126 :     =item RETURN
127 :    
128 :     Returns a list of tuples. The first element in the tuple is an object ID, the
129 :     second is an attribute key, and the remaining elements are the sections of
130 :     the attribute value. All of the tuples will match the criteria set forth in
131 :     the parameter list.
132 :    
133 :     =back
134 :    
135 :     =cut
136 :    
137 :     sub GetAttributes {
138 :     # Get the parameters.
139 :     my ($self, $objectID, $key, @valuePatterns) = @_;
140 :     Trace("Calling the remote custom attributes server.") if T(3);
141 :     # Call the remote server.
142 :     my $result = $self->{proxy}->call('GetAttributes', $objectID, $key, @valuePatterns);
143 :     Trace("Result type is " . ref($result) . ".") if T(3);
144 :     Trace(scalar(@{$result}) . " rows found.") if T(3) && ref($result) eq 'ARRAY';
145 :     # Unwrap the list and return it.
146 :     my @retVal = @{$result};
147 :     return @retVal;
148 :     }
149 :    
150 : parrello 1.6 =head3 QueryAttributes
151 :    
152 : parrello 1.8 my @attributeData = $ca->QueryAttributes($filter, $filterParms);
153 : parrello 1.6
154 :     Return the attribute data based on an SQL filter clause. In the filter clause,
155 :     the name C<$object> should be used for the object ID, C<$key> should be used for
156 :     the key name, C<$subkey> for the subkey value, and C<$value> for the value field.
157 :    
158 :     =over 4
159 :    
160 :     =item filter
161 :    
162 :     Filter clause in the standard ERDB format, except that the field names are C<$object> for
163 :     the object ID field, C<$key> for the key name field, C<$subkey> for the subkey field,
164 :     and C<$value> for the value field. This abstraction enables us to hide the details of
165 :     the database construction from the user.
166 :    
167 :     =item filterParms
168 :    
169 :     Parameters for the filter clause.
170 :    
171 :     =item RETURN
172 :    
173 :     Returns a list of tuples. Each tuple consists of an object ID, a key (with optional subkey), and
174 :     one or more attribute values.
175 :    
176 :     =back
177 :    
178 :     =cut
179 :    
180 :     sub QueryAttributes {
181 :     # Get the parameters.
182 :     my ($self, $filter, $filterParms) = @_;
183 :     Trace("Calling the remote custom attributes server.") if T(3);
184 :     # Call the remote server.
185 :     my $result = $self->{proxy}->call('QueryAttributes', $filter, $filterParms);
186 :     Trace("Result type is " . ref($result) . ".") if T(3);
187 :     Trace(scalar(@{$result}) . " rows found.") if T(3) && ref($result) eq 'ARRAY';
188 :     # Unwrap the list and return it.
189 :     my @retVal = @{$result};
190 :     return @retVal;
191 :     }
192 :    
193 : parrello 1.1 =head3 AddAttribute
194 :    
195 : parrello 1.8 $attrDB->AddAttribute($objectID, $key, @values);
196 : parrello 1.1
197 :     Add an attribute key/value pair to an object. This method cannot add a new key, merely
198 :     add a value to an existing key. Use L</StoreAttributeKey> to create a new key.
199 :    
200 :     =over 4
201 :    
202 :     =item objectID
203 :    
204 :     ID of the genome or feature to which the attribute is to be added. In general, an ID that
205 :     starts with C<fig|> is treated as a feature ID, and an ID that is all digits and periods
206 :     is treated as a genome ID. For IDs of other types, this parameter should be a reference
207 :     to a 2-tuple consisting of the entity type name followed by the object ID.
208 :    
209 :     =item key
210 :    
211 :     Attribute key name. This corresponds to the name of a field in the database.
212 :    
213 :     =item values
214 :    
215 :     One or more values to be associated with the key. The values are joined together with
216 :     the splitter value before being stored as field values. This enables L</GetAttributes>
217 :     to split them apart during retrieval. The splitter value defaults to double colons C<::>.
218 :    
219 :     =back
220 :    
221 :     =cut
222 :    
223 :     sub AddAttribute {
224 :     # Get the parameters.
225 :     my ($self, $objectID, $key, @values) = @_;
226 :     # Don't allow undefs.
227 :     if (! defined($objectID)) {
228 :     Confess("No object ID specified for AddAttribute call.");
229 :     } elsif (! defined($key)) {
230 :     Confess("No attribute key specified for AddAttribute call.");
231 :     } elsif (! @values) {
232 :     Confess("No values specified in AddAttribute call for key $key.");
233 :     } else {
234 :     # Call the remote server.
235 :     my $result = $self->{proxy}->call('AddAttribute', $objectID, $key, @values);
236 :     }
237 :     # Return a one. We do this for backward compatability.
238 :     return 1;
239 :     }
240 :    
241 :     =head3 DeleteAttribute
242 :    
243 : parrello 1.8 $attrDB->DeleteAttribute($objectID, $key, @values);
244 : parrello 1.1
245 :     Delete the specified attribute key/value combination from the database.
246 :    
247 :     The first form will connect to the database and release it. The second form
248 :     uses the database connection contained in the object.
249 :    
250 :     =over 4
251 :    
252 :     =item objectID
253 :    
254 :     ID of the genome or feature to which the attribute is to be added. In general, an ID that
255 :     starts with C<fig|> is treated as a feature ID, and an ID that is all digits and periods
256 :     is treated as a genome ID. For IDs of other types, this parameter should be a reference
257 :     to a 2-tuple consisting of the entity type name followed by the object ID.
258 :    
259 :     =item key
260 :    
261 :     Attribute key name. This corresponds to the name of a field in the database.
262 :    
263 :     =item values
264 :    
265 :     One or more values to be associated with the key.
266 :    
267 :     =back
268 :    
269 :     =cut
270 :    
271 :     sub DeleteAttribute {
272 :     # Get the parameters.
273 :     my ($self, $objectID, $key, @values) = @_;
274 :     # Don't allow undefs.
275 :     if (! defined($objectID)) {
276 :     Confess("No object ID specified for DeleteAttribute call.");
277 :     } elsif (! defined($key)) {
278 :     Confess("No attribute key specified for DeleteAttribute call.");
279 :     } elsif (! @values) {
280 :     Confess("No values specified in DeleteAttribute call for key $key.");
281 :     } else {
282 :     # Call the remote server.
283 :     my $result = $self->{proxy}->call('DeleteAttribute', $objectID, $key, @values);
284 :     }
285 :     # Return a one. This is for backward compatability.
286 :     return 1;
287 :     }
288 :    
289 :     =head3 ChangeAttribute
290 :    
291 : parrello 1.8 $attrDB->ChangeAttribute($objectID, $key, \@oldValues, \@newValues);
292 : parrello 1.1
293 :     Change the value of an attribute key/value pair for an object.
294 :    
295 :     =over 4
296 :    
297 :     =item objectID
298 :    
299 :     ID of the genome or feature to which the attribute is to be changed. In general, an ID that
300 :     starts with C<fig|> is treated as a feature ID, and an ID that is all digits and periods
301 :     is treated as a genome ID. For IDs of other types, this parameter should be a reference
302 :     to a 2-tuple consisting of the entity type name followed by the object ID.
303 :    
304 :     =item key
305 :    
306 :     Attribute key name. This corresponds to the name of a field in the database.
307 :    
308 :     =item oldValues
309 :    
310 :     One or more values identifying the key/value pair to change.
311 :    
312 :     =item newValues
313 :    
314 :     One or more values to be put in place of the old values.
315 :    
316 :     =back
317 :    
318 :     =cut
319 :    
320 :     sub ChangeAttribute {
321 :     # Get the parameters.
322 :     my ($self, $objectID, $key, $oldValues, $newValues) = @_;
323 :     # Don't allow undefs.
324 :     if (! defined($objectID)) {
325 :     Confess("No object ID specified for ChangeAttribute call.");
326 :     } elsif (! defined($key)) {
327 :     Confess("No attribute key specified for ChangeAttribute call.");
328 :     } elsif (! defined($oldValues) || ref $oldValues ne 'ARRAY') {
329 :     Confess("No old values specified in ChangeAttribute call for key $key.");
330 :     } elsif (! defined($newValues) || ref $newValues ne 'ARRAY') {
331 :     Confess("No new values specified in ChangeAttribute call for key $key.");
332 :     } else {
333 :     # Call the remote server.
334 :     my $result = $self->{proxy}->call('ChangeAttribute', $objectID, $key, $oldValues, $newValues);
335 :     }
336 :     # Return a one. We do this for backward compatability.
337 :     return 1;
338 :     }
339 :    
340 : parrello 1.2 =head3 EraseAttribute
341 :    
342 : parrello 1.8 $attrDB->EraseAttribute($entityName, $key);
343 : parrello 1.2
344 :     Erase all values for the specified attribute key. This does not remove the
345 :     key from the database; it merely removes all the values.
346 :    
347 :     =over 4
348 :    
349 :     =item entityName
350 :    
351 :     Name of the entity to which the key belongs. If undefined, all entities will be
352 :     examined for the desired key.
353 :    
354 :     =item key
355 :    
356 :     Key to erase.
357 :    
358 :     =back
359 :    
360 :     =cut
361 :    
362 :     sub EraseAttribute {
363 :     # Get the parameters.
364 :     my ($self, $entityName, $key) = @_;
365 :     # Call the remote server.
366 :     my $result = $self->{proxy}->call('EraseAttribute', $entityName, $key);
367 :     # Return a 1, for backward compatability.
368 :     return 1;
369 :     }
370 :    
371 : parrello 1.3 =head3 GetAttributeKeys
372 :    
373 : parrello 1.8 my @keyList = $attrDB->GetAttributeKeys($entityName);
374 : parrello 1.3
375 :     Return a list of the attribute keys for a particular entity type.
376 :    
377 :     =over 4
378 :    
379 :     =item entityName
380 :    
381 :     Name of the entity whose keys are desired.
382 :    
383 :     =item RETURN
384 :    
385 :     Returns a list of the attribute keys for the specified entity.
386 :    
387 :     =back
388 :    
389 :     =cut
390 :    
391 :     sub GetAttributeKeys {
392 :     # Get the parameters.
393 :     my ($self, $entityName) = @_;
394 :     # Call the remote server.
395 :     my $result = $self->{proxy}->call('GetAttributeKeys', $entityName);
396 :     Trace("Result type is " . ref($result) . ".") if T(3);
397 :     Trace(scalar(@{$result}) . " keys found.") if T(3) && ref($result) eq 'ARRAY';
398 :     # Unwrap the list and return it.
399 :     my @retVal = @{$result};
400 :     return @retVal;
401 :     }
402 :    
403 : parrello 1.5 =head3 DeleteMatchingAttributes
404 : parrello 1.4
405 : parrello 1.8 my @deleted = $attrDB->DeleteMatchingAttributes($objectID, $key, @values);
406 : parrello 1.4
407 : parrello 1.5 Delete all attributes that match the specified criteria. This is equivalent to
408 :     calling L</GetAttributes> and then invoking L</DeleteAttribute> for each
409 :     row found.
410 : parrello 1.4
411 :     =over 4
412 :    
413 : parrello 1.5 =item objectID
414 : parrello 1.4
415 : parrello 1.5 ID of object whose attributes are to be deleted. If the attributes for multiple
416 :     objects are to be deleted, this parameter can be specified as a list reference. If
417 :     attributes are to be deleted for all objects, specify C<undef> or an empty string.
418 :     Finally, you can delete attributes for a range of object IDs by putting a percent
419 :     sign (C<%>) at the end.
420 :    
421 :     =item key
422 :    
423 :     Attribute key name. A value of C<undef> or an empty string will match all
424 :     attribute keys. If the values are to be deletedfor multiple keys, this parameter can be
425 :     specified as a list reference. Finally, you can delete attributes for a range of
426 :     keys by putting a percent sign (C<%>) at the end.
427 :    
428 :     =item values
429 :    
430 :     List of the desired attribute values, section by section. If C<undef>
431 :     or an empty string is specified, all values in that section will match. A
432 :     generic match can be requested by placing a percent sign (C<%>) at the end.
433 :     In that case, all values that match up to and not including the percent sign
434 :     will match. You may also specify a regular expression enclosed
435 :     in slashes. All values that match the regular expression will be deleted. For
436 :     performance reasons, only values have this extra capability.
437 : parrello 1.4
438 :     =item RETURN
439 :    
440 : parrello 1.5 Returns a list of tuples for the attributes that were deleted, in the
441 :     same form as L</GetAttributes>.
442 : parrello 1.4
443 :     =back
444 :    
445 :     =cut
446 :    
447 : parrello 1.5 sub DeleteMatchingAttributes {
448 : parrello 1.4 # Get the parameters.
449 : parrello 1.5 my ($self, $objectID, $key, @values) = @_;
450 : parrello 1.4 # Call the remote server.
451 : parrello 1.5 my $result = $self->{proxy}->call('DeleteMatchingAttributes', $objectID, $key, @values);
452 : parrello 1.4 Trace("Result type is " . ref($result) . ".") if T(3);
453 : parrello 1.5 Trace(scalar(@{$result}) . " matches found.") if T(3) && ref($result) eq 'ARRAY';
454 : parrello 1.4 # Unwrap the list and return it.
455 :     my @retVal = @{$result};
456 :     return @retVal;
457 :     }
458 : parrello 1.3
459 : parrello 1.7 =head3 GetAttributeData
460 :    
461 : parrello 1.8 my %keys = $attrDB->GetAttributeData($type, @list);
462 : parrello 1.7
463 :     Return attribute data for the selected attributes. The attribute
464 :     data is a hash mapping each attribute key name to a n-tuple containing the
465 :     data type, the description, and the groups. This is the same format expected in
466 :     the L</FieldMenu> and L</ControlForm> methods for the list of attributes to display.
467 :    
468 :     =over 4
469 :    
470 :     =item type
471 :    
472 :     Type of attribute criterion: C<name> for attributes whose names begin with the
473 :     specified string, or C<group> for attributes in the specified group.
474 :    
475 :     =item list
476 :    
477 :     List containing the names of the groups or keys for the desired attributes.
478 :    
479 :     =item RETURN
480 :    
481 :     Returns a hash mapping each attribute key name to its data type, description, and
482 :     parent groups.
483 :    
484 :     =back
485 :    
486 :     =cut
487 :    
488 :     sub GetAttributeData {
489 :     # Get the parameters.
490 :     my ($self, $type, @list) = @_;
491 :     # Call the remote server.
492 :     my $result = $self->{proxy}->call('GetAttributeData', $type, @list);
493 :     Trace("Result type is " . ref($result) . ".") if T(3);
494 :     Trace(scalar(@{$result}) . " matches found.") if T(3) && ref($result) eq 'ARRAY';
495 :     # Unwrap the list as a hash and return it.
496 :     my %retVal = @{$result};
497 :     return %retVal;
498 :     }
499 :    
500 : parrello 1.1 1;

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3