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

Annotation of /Sprout/ERDBQuery.pm

Parent Directory Parent Directory | Revision Log Revision Log


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

1 : parrello 1.1 package ERDBQuery;
2 :    
3 :     use strict;
4 :     use DBKernel;
5 :     use ERDBObject;
6 :     use DBI;
7 :     use Tracer;
8 :    
9 :     =head1 Entity-Relationship Database Package Query Iterator
10 :    
11 :     =head2 Introduction
12 :    
13 :     This package defines the Iteration object for an Entity-Relationship Database. The iteration object
14 :     represents a filtered SELECT statement against an Entity-Relationship Database, and provides
15 :     methods for getting the appropriate records.
16 :    
17 :     There are two common ways an iteration object can be created. An I<entity iterator> is created when the
18 :     client asks for objects of a given entity type. A I<relationship iterator> is created when the
19 :     client asks for objects across a relationship starting from a specific entity instance. The
20 :     entity iterator returns a single object at each position; the relationship iterator returns two
21 :     objects at each position-- one for the target entity, and one for the relationship instance
22 :     that connects it to the source entity.
23 :    
24 :     For example, a client could ask for all B<Feature> instances that are marked active. This would
25 :     return an entity iterator. Each position in the iteration would consist of a single
26 :     B<Feature> instance. From a specific B<Feature> instance, the client could decide to cross the
27 :     B<IsLocatedIn> relationship to get all the B<Contig> instances which contain residues that
28 :     participate in the feature. This would return a relationship iterator. Each position in the
29 :     iterator would contain a single B<IsLocatedIn> instance and a single B<Contig> instance.
30 :    
31 :     At each point in the result set, the iterator returns a B<ERDBObject>. The ERDBObject allows the
32 :     client to access the fields of the current entity or relationship instance.
33 :    
34 :     It is also possible to ask for many different objects in a single iterator by chaining long
35 :     sequences of entities together by relationships. This is discussed in the documentation for the
36 :     B<ERDB> object's C<Get> method.
37 :    
38 :     Finally, objects of this type should never by created directly. Instead, they are created
39 :     by the aforementioned C<Get> method and the B<ERDBObject>'s C<Cross> method.
40 :    
41 :     =head2 Public Methods
42 :    
43 :     =head3 Fetch
44 :    
45 :     my $dbObject = $dbQuery->Fetch();
46 :    
47 :     Retrieve a record from this query. The record returned will be a B<ERDBObject>, which
48 :     may represent a single entity instance or a list of entity instances joined by relationships.
49 :     The first time this method is called it will return the first result from query. After that it
50 :     will continue sequentially. It will return an undefined value if we've reached the end of the
51 :     result set.
52 :    
53 :     =cut
54 :    
55 :     sub Fetch {
56 :     # Get the parameters;
57 :     my ($self) = @_;
58 :     # Declare the return variable.
59 :     my $retVal;
60 :     # Fetch the next row in the query result set.
61 :     my $sth = $self->{_sth};
62 :     my @row = $sth->fetchrow;
63 :     # Check to see if we got any results.
64 :     if (@row == 0) {
65 :     # Here we have no result. If we're at the end of the result set, this is okay, because
66 :     # we'll be returning an undefined value in $retVal. If an error occurred, we need to abort.
67 :     if ($sth->err) {
68 :     Confess("FETCH error: " . $sth->err);
69 :     } else {
70 :     # Trace the number of results returned.
71 :     Trace("$self->{_results} rows processed by query.") if T(SQL => 4);
72 :     }
73 :     } else {
74 :     # Here we have a result, so we need to turn it into an instance object.
75 :     $retVal = ERDBObject->_new($self, @row);
76 :     $self->{_results}++;
77 :     }
78 :     # Return the result.
79 :     return $retVal;
80 :     }
81 :    
82 : parrello 1.2 =head3 DefaultObjectName
83 :    
84 :     my $objectName = $query->DefaultObjectName();
85 :    
86 :     Return the name of this query's default entity or relationship.
87 :    
88 :     =cut
89 :    
90 :     sub DefaultObjectName {
91 :     # Get the parameters.
92 :     my ($self) = @_;
93 :     # Get the relation map.
94 :     my $map = $self->{_objectNames};
95 :     # Get the default object alias. This is always the first alias in the
96 :     # relation map.
97 :     my $retVal = $map->[0][0];
98 :     # Return the result.
99 :     return $retVal;
100 :     }
101 :    
102 :    
103 : parrello 1.1 =head3 AnalyzeFieldName
104 :    
105 :     my ($objectName, $fieldName, $type) = $query->AnalyzeFieldName($name);
106 :    
107 :     Analyze a field name (such as might be found in a [[ErdbPm#GetAll]]
108 :     parameter list) and return the real name of the relevant entity or
109 :     relationship, the field name itself, and the associated type object
110 :     (which will be a subclass of [[ERDBTypePm]].
111 :    
112 :     =over 4
113 :    
114 :     =item name
115 :    
116 :     Field name to examine, in the standard field name format used by [[ErdbPm]].
117 :    
118 :     =item RETURN
119 :    
120 :     Returns a 3-tuple containing the name of the object containing the field, the
121 :     base field name, and a type object describing the field's type.
122 :    
123 :     =back
124 :    
125 :     =cut
126 :    
127 :     sub AnalyzeFieldName {
128 :     # Get the parameters.
129 :     my ($self, $name) = @_;
130 :     # Declare the return variables.
131 :     my ($objectName, $fieldName, $type);
132 :     # Get the relation map.
133 :     my $map = $self->{_objectNames};
134 :     # Get the default object alias. This is always the first alias in the
135 :     # relation map.
136 :     my $defaultName = $map->[0][0];
137 :     # Parse the field name.
138 :     my $alias;
139 :     ($alias, $fieldName) = ERDB::ParseFieldName($name, $defaultName);
140 :     if (! defined $alias) {
141 :     Confess("Field identifier \"$name\" has an invalid format.");
142 :     } else {
143 :     # Find the alias in the relation map.
144 :     my ($aliasTuple) = grep { $_->[0] eq $alias } @$map;
145 :     if (! defined $aliasTuple) {
146 :     Confess("Object name \"$alias\" not found in query.");
147 :     } else {
148 :     # Get the real object name.
149 :     my $objectName = $aliasTuple->[1];
150 :     # Ask the database for the field descriptor. If the field name is
151 :     # invalid, this will throw an error.
152 :     my $fieldData = $self->{_db}->_FindField($fieldName, $objectName);
153 :     # Extract the field type.
154 :     my $typeName = $fieldData->{type};
155 :     # Get the corresponding type object.
156 :     $type = ERDB::GetDataTypes()->{$typeName};
157 :    
158 :     }
159 :     }
160 :     # Return the results.
161 :     return ($objectName, $fieldName, $type);
162 :     }
163 :    
164 :    
165 :     =head2 Internal Methods
166 :    
167 :     =head3 _new
168 :    
169 :     my $query = ERDBQuery->new($database, $sth, $relationMap, $searchObject);
170 :    
171 :     Create a new query object.
172 :    
173 :     =over 4
174 :    
175 :     =item database
176 :    
177 :     ERDB object for the relevant database.
178 :    
179 :     =item sth
180 :    
181 :     Statement handle for the SELECT clause generated by the query.
182 :    
183 :     =item relationMap
184 :    
185 :     Reference to a list of 2-tuples. Each tuple consists of an object name as used
186 :     in the query followed by the actual name of that object. This enables the
187 :     B<ERDBObject> to determine the order of the tables in the query and which object
188 :     name belongs to each mapped object name. Most of the time these two values are
189 :     the same; however, if a relation occurs twice in the query, the relation name in
190 :     the field list and WHERE clause will use a mapped name (generally the actual
191 :     relation name with a numeric suffix) that does not match the actual relation
192 :     name.
193 :    
194 :     =item searchObject (optional)
195 :    
196 :     If specified, then the query is a full-text search, and the first field will be a
197 :     relevance indicator for the named table.
198 :    
199 :     =back
200 :    
201 :     =cut
202 :    
203 :     sub _new {
204 :     # Get the parameters.
205 :     my ($database, $sth, $relationMap, $searchObject) = @_;
206 :     # Create this object.
207 :     my $self = { _db => $database, _sth => $sth, _objectNames => $relationMap,
208 :     _fullText => $searchObject, _results => 0 };
209 :     # Bless and return it.
210 :     bless $self;
211 :     return $self;
212 :     }
213 :    
214 :     1;

MCS Webmaster
ViewVC Help
Powered by ViewVC 1.0.3