File | /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/Relationship/Base.pm | Statements Executed | 15 | Total Time | 0.001159 seconds |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine | |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | BEGIN |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | count_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | create_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | delete_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | find_or_create_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | find_or_new_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | find_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | new_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | register_relationship |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | related_resultset |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | search_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | search_related_rs |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | set_from_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | update_from_related |
0 | 0 | 0 | 0 | 0 | DBIx::Class::Relationship::Base:: | update_or_create_related |
Line | Stmts. | Exclusive Time | Avg. | Code |
---|---|---|---|---|
1 | package DBIx::Class::Relationship::Base; | |||
2 | ||||
3 | 3 | 3.3e-5 | 1.1e-5 | use strict; # spent 10µs making 1 call to strict::import |
4 | 3 | 3.8e-5 | 1.3e-5 | use warnings; # spent 31µs making 1 call to warnings::import |
5 | ||||
6 | 3 | 3.0e-5 | 1.0e-5 | use Scalar::Util (); |
7 | 3 | 0.00105 | 0.00035 | use base qw/DBIx::Class/; # spent 70µs making 1 call to base::import |
8 | ||||
9 | =head1 NAME | |||
10 | ||||
11 | DBIx::Class::Relationship::Base - Inter-table relationships | |||
12 | ||||
13 | =head1 SYNOPSIS | |||
14 | ||||
15 | =head1 DESCRIPTION | |||
16 | ||||
17 | This class provides methods to describe the relationships between the | |||
18 | tables in your database model. These are the "bare bones" relationships | |||
19 | methods, for predefined ones, look in L<DBIx::Class::Relationship>. | |||
20 | ||||
21 | =head1 METHODS | |||
22 | ||||
23 | =head2 add_relationship | |||
24 | ||||
25 | =over 4 | |||
26 | ||||
27 | =item Arguments: 'relname', 'Foreign::Class', $cond, $attrs | |||
28 | ||||
29 | =back | |||
30 | ||||
31 | __PACKAGE__->add_relationship('relname', 'Foreign::Class', $cond, $attrs); | |||
32 | ||||
33 | The condition needs to be an L<SQL::Abstract>-style representation of the | |||
34 | join between the tables. When resolving the condition for use in a C<JOIN>, | |||
35 | keys using the pseudo-table C<foreign> are resolved to mean "the Table on the | |||
36 | other side of the relationship", and values using the pseudo-table C<self> | |||
37 | are resolved to mean "the Table this class is representing". Other | |||
38 | restrictions, such as by value, sub-select and other tables, may also be | |||
39 | used. Please check your database for C<JOIN> parameter support. | |||
40 | ||||
41 | For example, if you're creating a relationship from C<Author> to C<Book>, where | |||
42 | the C<Book> table has a column C<author_id> containing the ID of the C<Author> | |||
43 | row: | |||
44 | ||||
45 | { 'foreign.author_id' => 'self.id' } | |||
46 | ||||
47 | will result in the C<JOIN> clause | |||
48 | ||||
49 | author me JOIN book book ON book.author_id = me.id | |||
50 | ||||
51 | For multi-column foreign keys, you will need to specify a C<foreign>-to-C<self> | |||
52 | mapping for each column in the key. For example, if you're creating a | |||
53 | relationship from C<Book> to C<Edition>, where the C<Edition> table refers to a | |||
54 | publisher and a type (e.g. "paperback"): | |||
55 | ||||
56 | { | |||
57 | 'foreign.publisher_id' => 'self.publisher_id', | |||
58 | 'foreign.type_id' => 'self.type_id', | |||
59 | } | |||
60 | ||||
61 | This will result in the C<JOIN> clause: | |||
62 | ||||
63 | book me JOIN edition edition ON edition.publisher_id = me.publisher_id | |||
64 | AND edition.type_id = me.type_id | |||
65 | ||||
66 | Each key-value pair provided in a hashref will be used as C<AND>ed conditions. | |||
67 | To add an C<OR>ed condition, use an arrayref of hashrefs. See the | |||
68 | L<SQL::Abstract> documentation for more details. | |||
69 | ||||
70 | In addition to standard result set attributes, the following attributes are also valid: | |||
71 | ||||
72 | =over 4 | |||
73 | ||||
74 | =item join_type | |||
75 | ||||
76 | Explicitly specifies the type of join to use in the relationship. Any SQL | |||
77 | join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL | |||
78 | command immediately before C<JOIN>. | |||
79 | ||||
80 | =item proxy | |||
81 | ||||
82 | An arrayref containing a list of accessors in the foreign class to create in | |||
83 | the main class. If, for example, you do the following: | |||
84 | ||||
85 | MyDB::Schema::CD->might_have(liner_notes => 'MyDB::Schema::LinerNotes', | |||
86 | undef, { | |||
87 | proxy => [ qw/notes/ ], | |||
88 | }); | |||
89 | ||||
90 | Then, assuming MyDB::Schema::LinerNotes has an accessor named notes, you can do: | |||
91 | ||||
92 | my $cd = MyDB::Schema::CD->find(1); | |||
93 | $cd->notes('Notes go here'); # set notes -- LinerNotes object is | |||
94 | # created if it doesn't exist | |||
95 | ||||
96 | =item accessor | |||
97 | ||||
98 | Specifies the type of accessor that should be created for the relationship. | |||
99 | Valid values are C<single> (for when there is only a single related object), | |||
100 | C<multi> (when there can be many), and C<filter> (for when there is a single | |||
101 | related object, but you also want the relationship accessor to double as | |||
102 | a column accessor). For C<multi> accessors, an add_to_* method is also | |||
103 | created, which calls C<create_related> for the relationship. | |||
104 | ||||
105 | =item is_foreign_key_constraint | |||
106 | ||||
107 | If you are using L<SQL::Translator> to create SQL for you and you find that it | |||
108 | is creating constraints where it shouldn't, or not creating them where it | |||
109 | should, set this attribute to a true or false value to override the detection | |||
110 | of when to create constraints. | |||
111 | ||||
112 | =back | |||
113 | ||||
114 | =head2 register_relationship | |||
115 | ||||
116 | =over 4 | |||
117 | ||||
118 | =item Arguments: $relname, $rel_info | |||
119 | ||||
120 | =back | |||
121 | ||||
122 | Registers a relationship on the class. This is called internally by | |||
123 | DBIx::Class::ResultSourceProxy to set up Accessors and Proxies. | |||
124 | ||||
125 | =cut | |||
126 | ||||
127 | 2 | 1.0e-6 | 5.0e-7 | sub register_relationship { } |
128 | ||||
129 | =head2 related_resultset | |||
130 | ||||
131 | =over 4 | |||
132 | ||||
133 | =item Arguments: $relationship_name | |||
134 | ||||
135 | =item Return Value: $related_resultset | |||
136 | ||||
137 | =back | |||
138 | ||||
139 | $rs = $cd->related_resultset('artist'); | |||
140 | ||||
141 | Returns a L<DBIx::Class::ResultSet> for the relationship named | |||
142 | $relationship_name. | |||
143 | ||||
144 | =cut | |||
145 | ||||
146 | sub related_resultset { | |||
147 | my $self = shift; | |||
148 | $self->throw_exception("Can't call *_related as class methods") | |||
149 | unless ref $self; | |||
150 | my $rel = shift; | |||
151 | my $rel_obj = $self->relationship_info($rel); | |||
152 | $self->throw_exception( "No such relationship ${rel}" ) | |||
153 | unless $rel_obj; | |||
154 | ||||
155 | return $self->{related_resultsets}{$rel} ||= do { | |||
156 | my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {}); | |||
157 | $attrs = { %{$rel_obj->{attrs} || {}}, %$attrs }; | |||
158 | ||||
159 | $self->throw_exception( "Invalid query: @_" ) | |||
160 | if (@_ > 1 && (@_ % 2 == 1)); | |||
161 | my $query = ((@_ > 1) ? {@_} : shift); | |||
162 | ||||
163 | my $cond = $self->result_source->resolve_condition( | |||
164 | $rel_obj->{cond}, $rel, $self | |||
165 | ); | |||
166 | if (ref $cond eq 'ARRAY') { | |||
167 | $cond = [ map { my $hash; | |||
168 | foreach my $key (keys %$_) { | |||
169 | my $newkey = $key =~ /\./ ? "me.$key" : $key; | |||
170 | $hash->{$newkey} = $_->{$key}; | |||
171 | }; $hash } @$cond ]; | |||
172 | } else { | |||
173 | foreach my $key (grep { ! /\./ } keys %$cond) { | |||
174 | $cond->{"me.$key"} = delete $cond->{$key}; | |||
175 | } | |||
176 | } | |||
177 | $query = ($query ? { '-and' => [ $cond, $query ] } : $cond); | |||
178 | $self->result_source->related_source($rel)->resultset->search( | |||
179 | $query, $attrs | |||
180 | ); | |||
181 | }; | |||
182 | } | |||
183 | ||||
184 | =head2 search_related | |||
185 | ||||
186 | @objects = $rs->search_related('relname', $cond, $attrs); | |||
187 | $objects_rs = $rs->search_related('relname', $cond, $attrs); | |||
188 | ||||
189 | Run a search on a related resultset. The search will be restricted to the | |||
190 | item or items represented by the L<DBIx::Class::ResultSet> it was called | |||
191 | upon. This method can be called on a ResultSet, a Row or a ResultSource class. | |||
192 | ||||
193 | =cut | |||
194 | ||||
195 | sub search_related { | |||
196 | return shift->related_resultset(shift)->search(@_); | |||
197 | } | |||
198 | ||||
199 | =head2 search_related_rs | |||
200 | ||||
201 | ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs); | |||
202 | ||||
203 | This method works exactly the same as search_related, except that | |||
204 | it garauntees a restultset, even in list context. | |||
205 | ||||
206 | =cut | |||
207 | ||||
208 | sub search_related_rs { | |||
209 | return shift->related_resultset(shift)->search_rs(@_); | |||
210 | } | |||
211 | ||||
212 | =head2 count_related | |||
213 | ||||
214 | $obj->count_related('relname', $cond, $attrs); | |||
215 | ||||
216 | Returns the count of all the items in the related resultset, restricted by the | |||
217 | current item or where conditions. Can be called on a | |||
218 | L<DBIx::Class::Manual::Glossary/"ResultSet"> or a | |||
219 | L<DBIx::Class::Manual::Glossary/"Row"> object. | |||
220 | ||||
221 | =cut | |||
222 | ||||
223 | sub count_related { | |||
224 | my $self = shift; | |||
225 | return $self->search_related(@_)->count; | |||
226 | } | |||
227 | ||||
228 | =head2 new_related | |||
229 | ||||
230 | my $new_obj = $obj->new_related('relname', \%col_data); | |||
231 | ||||
232 | Create a new item of the related foreign class. If called on a | |||
233 | L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically | |||
234 | set any foreign key columns of the new object to the related primary | |||
235 | key columns of the source object for you. The newly created item will | |||
236 | not be saved into your storage until you call L<DBIx::Class::Row/insert> | |||
237 | on it. | |||
238 | ||||
239 | =cut | |||
240 | ||||
241 | sub new_related { | |||
242 | my ($self, $rel, $values, $attrs) = @_; | |||
243 | return $self->search_related($rel)->new($values, $attrs); | |||
244 | } | |||
245 | ||||
246 | =head2 create_related | |||
247 | ||||
248 | my $new_obj = $obj->create_related('relname', \%col_data); | |||
249 | ||||
250 | Creates a new item, similarly to new_related, and also inserts the item's data | |||
251 | into your storage medium. See the distinction between C<create> and C<new> | |||
252 | in L<DBIx::Class::ResultSet> for details. | |||
253 | ||||
254 | =cut | |||
255 | ||||
256 | sub create_related { | |||
257 | my $self = shift; | |||
258 | my $rel = shift; | |||
259 | my $obj = $self->search_related($rel)->create(@_); | |||
260 | delete $self->{related_resultsets}->{$rel}; | |||
261 | return $obj; | |||
262 | } | |||
263 | ||||
264 | =head2 find_related | |||
265 | ||||
266 | my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals); | |||
267 | ||||
268 | Attempt to find a related object using its primary key or unique constraints. | |||
269 | See L<DBIx::Class::ResultSet/find> for details. | |||
270 | ||||
271 | =cut | |||
272 | ||||
273 | sub find_related { | |||
274 | my $self = shift; | |||
275 | my $rel = shift; | |||
276 | return $self->search_related($rel)->find(@_); | |||
277 | } | |||
278 | ||||
279 | =head2 find_or_new_related | |||
280 | ||||
281 | my $new_obj = $obj->find_or_new_related('relname', \%col_data); | |||
282 | ||||
283 | Find an item of a related class. If none exists, instantiate a new item of the | |||
284 | related class. The object will not be saved into your storage until you call | |||
285 | L<DBIx::Class::Row/insert> on it. | |||
286 | ||||
287 | =cut | |||
288 | ||||
289 | sub find_or_new_related { | |||
290 | my $self = shift; | |||
291 | return $self->find_related(@_) || $self->new_related(@_); | |||
292 | } | |||
293 | ||||
294 | =head2 find_or_create_related | |||
295 | ||||
296 | my $new_obj = $obj->find_or_create_related('relname', \%col_data); | |||
297 | ||||
298 | Find or create an item of a related class. See | |||
299 | L<DBIx::Class::ResultSet/find_or_create> for details. | |||
300 | ||||
301 | =cut | |||
302 | ||||
303 | sub find_or_create_related { | |||
304 | my $self = shift; | |||
305 | my $obj = $self->find_related(@_); | |||
306 | return (defined($obj) ? $obj : $self->create_related(@_)); | |||
307 | } | |||
308 | ||||
309 | =head2 update_or_create_related | |||
310 | ||||
311 | my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?); | |||
312 | ||||
313 | Update or create an item of a related class. See | |||
314 | L<DBIx::Class::ResultSet/update_or_create> for details. | |||
315 | ||||
316 | =cut | |||
317 | ||||
318 | sub update_or_create_related { | |||
319 | my $self = shift; | |||
320 | my $rel = shift; | |||
321 | return $self->related_resultset($rel)->update_or_create(@_); | |||
322 | } | |||
323 | ||||
324 | =head2 set_from_related | |||
325 | ||||
326 | $book->set_from_related('author', $author_obj); | |||
327 | $book->author($author_obj); ## same thing | |||
328 | ||||
329 | Set column values on the current object, using related values from the given | |||
330 | related object. This is used to associate previously separate objects, for | |||
331 | example, to set the correct author for a book, find the Author object, then | |||
332 | call set_from_related on the book. | |||
333 | ||||
334 | This is called internally when you pass existing objects as values to | |||
335 | L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to acessor. | |||
336 | ||||
337 | The columns are only set in the local copy of the object, call L</update> to | |||
338 | set them in the storage. | |||
339 | ||||
340 | =cut | |||
341 | ||||
342 | sub set_from_related { | |||
343 | my ($self, $rel, $f_obj) = @_; | |||
344 | my $rel_obj = $self->relationship_info($rel); | |||
345 | $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj; | |||
346 | my $cond = $rel_obj->{cond}; | |||
347 | $self->throw_exception( | |||
348 | "set_from_related can only handle a hash condition; the ". | |||
349 | "condition for $rel is of type ". | |||
350 | (ref $cond ? ref $cond : 'plain scalar') | |||
351 | ) unless ref $cond eq 'HASH'; | |||
352 | if (defined $f_obj) { | |||
353 | my $f_class = $self->result_source->schema->class($rel_obj->{class}); | |||
354 | $self->throw_exception( "Object $f_obj isn't a ".$f_class ) | |||
355 | unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class); | |||
356 | } | |||
357 | $self->set_columns( | |||
358 | $self->result_source->resolve_condition( | |||
359 | $rel_obj->{cond}, $f_obj, $rel)); | |||
360 | return 1; | |||
361 | } | |||
362 | ||||
363 | =head2 update_from_related | |||
364 | ||||
365 | $book->update_from_related('author', $author_obj); | |||
366 | ||||
367 | The same as L</"set_from_related">, but the changes are immediately updated | |||
368 | in storage. | |||
369 | ||||
370 | =cut | |||
371 | ||||
372 | sub update_from_related { | |||
373 | my $self = shift; | |||
374 | $self->set_from_related(@_); | |||
375 | $self->update; | |||
376 | } | |||
377 | ||||
378 | =head2 delete_related | |||
379 | ||||
380 | $obj->delete_related('relname', $cond, $attrs); | |||
381 | ||||
382 | Delete any related item subject to the given conditions. | |||
383 | ||||
384 | =cut | |||
385 | ||||
386 | sub delete_related { | |||
387 | my $self = shift; | |||
388 | my $obj = $self->search_related(@_)->delete; | |||
389 | delete $self->{related_resultsets}->{$_[0]}; | |||
390 | return $obj; | |||
391 | } | |||
392 | ||||
393 | =head2 add_to_$rel | |||
394 | ||||
395 | B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type | |||
396 | relationships.> | |||
397 | ||||
398 | =over 4 | |||
399 | ||||
400 | =item Arguments: ($foreign_vals | $obj), $link_vals? | |||
401 | ||||
402 | =back | |||
403 | ||||
404 | my $role = $schema->resultset('Role')->find(1); | |||
405 | $actor->add_to_roles($role); | |||
406 | # creates a My::DBIC::Schema::ActorRoles linking table row object | |||
407 | ||||
408 | $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 }); | |||
409 | # creates a new My::DBIC::Schema::Role row object and the linking table | |||
410 | # object with an extra column in the link | |||
411 | ||||
412 | Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first | |||
413 | argument is a hash reference, the related object is created first with the | |||
414 | column values in the hash. If an object reference is given, just the linking | |||
415 | table object is created. In either case, any additional column values for the | |||
416 | linking table object can be specified in C<$link_vals>. | |||
417 | ||||
418 | =head2 set_$rel | |||
419 | ||||
420 | B<Currently only available for C<many-to-many> relationships.> | |||
421 | ||||
422 | =over 4 | |||
423 | ||||
424 | =item Arguments: (\@hashrefs | \@objs) | |||
425 | ||||
426 | =back | |||
427 | ||||
428 | my $actor = $schema->resultset('Actor')->find(1); | |||
429 | my @roles = $schema->resultset('Role')->search({ role => | |||
430 | { '-in' -> ['Fred', 'Barney'] } } ); | |||
431 | ||||
432 | $actor->set_roles(\@roles); | |||
433 | # Replaces all of $actor's previous roles with the two named | |||
434 | ||||
435 | Replace all the related objects with the given reference to a list of | |||
436 | objects. This does a C<delete> B<on the link table resultset> to remove the | |||
437 | association between the current object and all related objects, then calls | |||
438 | C<add_to_$rel> repeatedly to link all the new objects. | |||
439 | ||||
440 | Note that this means that this method will B<not> delete any objects in the | |||
441 | table on the right side of the relation, merely that it will delete the link | |||
442 | between them. | |||
443 | ||||
444 | Due to a mistake in the original implementation of this method, it will also | |||
445 | accept a list of objects or hash references. This is B<deprecated> and will be | |||
446 | removed in a future version. | |||
447 | ||||
448 | =head2 remove_from_$rel | |||
449 | ||||
450 | B<Currently only available for C<many-to-many> relationships.> | |||
451 | ||||
452 | =over 4 | |||
453 | ||||
454 | =item Arguments: $obj | |||
455 | ||||
456 | =back | |||
457 | ||||
458 | my $role = $schema->resultset('Role')->find(1); | |||
459 | $actor->remove_from_roles($role); | |||
460 | # removes $role's My::DBIC::Schema::ActorRoles linking table row object | |||
461 | ||||
462 | Removes the link between the current object and the related object. Note that | |||
463 | the related object itself won't be deleted unless you call ->delete() on | |||
464 | it. This method just removes the link between the two objects. | |||
465 | ||||
466 | =head1 AUTHORS | |||
467 | ||||
468 | Matt S. Trout <mst@shadowcatsystems.co.uk> | |||
469 | ||||
470 | =head1 LICENSE | |||
471 | ||||
472 | You may distribute this code under the same terms as Perl itself. | |||
473 | ||||
474 | =cut | |||
475 | ||||
476 | 1 | 3.0e-6 | 3.0e-6 | 1; |