← Index
NYTProf Performance Profile   « block view • line view • sub view »
For xt/tapper-mcp-scheduler-with-db-longrun.t
  Run on Tue May 22 17:18:39 2012
Reported on Tue May 22 17:22:36 2012

Filename/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/Relationship/Base.pm
StatementsExecuted 92555 statements in 320ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
544011258ms2.35sDBIx::Class::Relationship::Base::::related_resultsetDBIx::Class::Relationship::Base::related_resultset
54403354.1ms3.72sDBIx::Class::Relationship::Base::::search_relatedDBIx::Class::Relationship::Base::search_related
16541124.1ms5.20sDBIx::Class::Relationship::Base::::find_relatedDBIx::Class::Relationship::Base::find_related
35311118.3ms147msDBIx::Class::Relationship::Base::::__ANON__[:422]DBIx::Class::Relationship::Base::__ANON__[:422]
3531114.60ms4.60msDBIx::Class::Relationship::Base::::CORE:matchDBIx::Class::Relationship::Base::CORE:match (opcode)
601148µs48µsDBIx::Class::Relationship::Base::::register_relationshipDBIx::Class::Relationship::Base::register_relationship
11114µs16µsDBIx::Class::Relationship::Base::::BEGIN@3DBIx::Class::Relationship::Base::BEGIN@3
1119µs43µsDBIx::Class::Relationship::Base::::BEGIN@9DBIx::Class::Relationship::Base::BEGIN@9
1118µs51µsDBIx::Class::Relationship::Base::::BEGIN@8DBIx::Class::Relationship::Base::BEGIN@8
1117µs183µsDBIx::Class::Relationship::Base::::BEGIN@10DBIx::Class::Relationship::Base::BEGIN@10
1117µs15µsDBIx::Class::Relationship::Base::::BEGIN@4DBIx::Class::Relationship::Base::BEGIN@4
1117µs66µsDBIx::Class::Relationship::Base::::BEGIN@6DBIx::Class::Relationship::Base::BEGIN@6
0000s0sDBIx::Class::Relationship::Base::::__ANON__[:429]DBIx::Class::Relationship::Base::__ANON__[:429]
0000s0sDBIx::Class::Relationship::Base::::count_relatedDBIx::Class::Relationship::Base::count_related
0000s0sDBIx::Class::Relationship::Base::::create_relatedDBIx::Class::Relationship::Base::create_related
0000s0sDBIx::Class::Relationship::Base::::delete_relatedDBIx::Class::Relationship::Base::delete_related
0000s0sDBIx::Class::Relationship::Base::::find_or_create_relatedDBIx::Class::Relationship::Base::find_or_create_related
0000s0sDBIx::Class::Relationship::Base::::find_or_new_relatedDBIx::Class::Relationship::Base::find_or_new_related
0000s0sDBIx::Class::Relationship::Base::::new_relatedDBIx::Class::Relationship::Base::new_related
0000s0sDBIx::Class::Relationship::Base::::search_related_rsDBIx::Class::Relationship::Base::search_related_rs
0000s0sDBIx::Class::Relationship::Base::::set_from_relatedDBIx::Class::Relationship::Base::set_from_related
0000s0sDBIx::Class::Relationship::Base::::update_from_relatedDBIx::Class::Relationship::Base::update_from_related
0000s0sDBIx::Class::Relationship::Base::::update_or_create_relatedDBIx::Class::Relationship::Base::update_or_create_related
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1package DBIx::Class::Relationship::Base;
2
3318µs218µs
# spent 16µs (14+2) within DBIx::Class::Relationship::Base::BEGIN@3 which was called: # once (14µs+2µs) by Class::C3::Componentised::ensure_class_loaded at line 3
use strict;
# spent 16µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@3 # spent 2µs making 1 call to strict::import
4319µs224µs
# spent 15µs (7+8) within DBIx::Class::Relationship::Base::BEGIN@4 which was called: # once (7µs+8µs) by Class::C3::Componentised::ensure_class_loaded at line 4
use warnings;
# spent 15µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@4 # spent 8µs making 1 call to warnings::import
5
6321µs2124µs
# spent 66µs (7+58) within DBIx::Class::Relationship::Base::BEGIN@6 which was called: # once (7µs+58µs) by Class::C3::Componentised::ensure_class_loaded at line 6
use base qw/DBIx::Class/;
# spent 66µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@6 # spent 58µs making 1 call to base::import
7
8320µs294µs
# spent 51µs (8+43) within DBIx::Class::Relationship::Base::BEGIN@8 which was called: # once (8µs+43µs) by Class::C3::Componentised::ensure_class_loaded at line 8
use Scalar::Util qw/weaken blessed/;
# spent 51µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@8 # spent 43µs making 1 call to Exporter::import
9318µs278µs
# spent 43µs (9+34) within DBIx::Class::Relationship::Base::BEGIN@9 which was called: # once (9µs+34µs) by Class::C3::Componentised::ensure_class_loaded at line 9
use Try::Tiny;
# spent 43µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@9 # spent 34µs making 1 call to Exporter::import
1031.25ms2359µs
# spent 183µs (7+176) within DBIx::Class::Relationship::Base::BEGIN@10 which was called: # once (7µs+176µs) by Class::C3::Componentised::ensure_class_loaded at line 10
use namespace::clean;
# spent 183µs making 1 call to DBIx::Class::Relationship::Base::BEGIN@10 # spent 176µs making 1 call to namespace::clean::import
11
12=head1 NAME
13
14DBIx::Class::Relationship::Base - Inter-table relationships
15
16=head1 SYNOPSIS
17
18 __PACKAGE__->add_relationship(
19 spiders => 'My::DB::Result::Creatures',
20 sub {
21 my $args = shift;
22 return {
23 "$args->{foreign_alias}.id" => { -ident => "$args->{self_alias}.id" },
24 "$args->{foreign_alias}.type" => 'arachnid'
25 };
26 },
27 );
28
29=head1 DESCRIPTION
30
31This class provides methods to describe the relationships between the
32tables in your database model. These are the "bare bones" relationships
33methods, for predefined ones, look in L<DBIx::Class::Relationship>.
34
35=head1 METHODS
36
37=head2 add_relationship
38
39=over 4
40
41=item Arguments: 'relname', 'Foreign::Class', $condition, $attrs
42
43=back
44
45 __PACKAGE__->add_relationship('relname',
46 'Foreign::Class',
47 $condition, $attrs);
48
49Create a custom relationship between one result source and another
50source, indicated by its class name.
51
52=head3 condition
53
54The condition argument describes the C<ON> clause of the C<JOIN>
55expression used to connect the two sources when creating SQL queries.
56
57To create simple equality joins, supply a hashref containing the
58remote table column name as the key(s), and the local table column
59name as the value(s), for example given:
60
61 My::Schema::Author->has_many(
62 books => 'My::Schema::Book',
63 { 'foreign.author_id' => 'self.id' }
64 );
65
66A query like:
67
68 $author_rs->search_related('books')->next
69
70will result in the following C<JOIN> clause:
71
72 ... FROM author me LEFT JOIN book books ON books.author_id = me.id ...
73
74This describes a relationship between the C<Author> table and the
75C<Book> table where the C<Book> table has a column C<author_id>
76containing the ID value of the C<Author>.
77
78C<foreign> and C<self> are pseudo aliases and must be entered
79literally. They will be replaced with the actual correct table alias
80when the SQL is produced.
81
82Similarly:
83
84 My::Schema::Book->has_many(
85 editions => 'My::Schema::Edition',
86 {
87 'foreign.publisher_id' => 'self.publisher_id',
88 'foreign.type_id' => 'self.type_id',
89 }
90 );
91
92 ...
93
94 $book_rs->search_related('editions')->next
95
96will result in the C<JOIN> clause:
97
98 ... FROM book me
99 LEFT JOIN edition editions ON
100 editions.publisher_id = me.publisher_id
101 AND editions.type_id = me.type_id ...
102
103This describes the relationship from C<Book> to C<Edition>, where the
104C<Edition> table refers to a publisher and a type (e.g. "paperback"):
105
106As is the default in L<SQL::Abstract>, the key-value pairs will be
107C<AND>ed in the result. C<OR> can be achieved with an arrayref, for
108example a condition like:
109
110 My::Schema::Item->has_many(
111 related_item_links => My::Schema::Item::Links,
112 [
113 { 'foreign.left_itemid' => 'self.id' },
114 { 'foreign.right_itemid' => 'self.id' },
115 ],
116 );
117
118will translate to the following C<JOIN> clause:
119
120 ... FROM item me JOIN item_relations related_item_links ON
121 related_item_links.left_itemid = me.id
122 OR related_item_links.right_itemid = me.id ...
123
124This describes the relationship from C<Item> to C<Item::Links>, where
125C<Item::Links> is a many-to-many linking table, linking items back to
126themselves in a peer fashion (without a "parent-child" designation)
127
128To specify joins which describe more than a simple equality of column
129values, the custom join condition coderef syntax can be used. For
130example:
131
132 My::Schema::Artist->has_many(
133 cds_80s => 'My::Schema::CD',
134 sub {
135 my $args = shift;
136
137 return {
138 "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
139 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
140 };
141 }
142 );
143
144 ...
145
146 $artist_rs->search_related('cds_80s')->next;
147
148will result in the C<JOIN> clause:
149
150 ... FROM artist me LEFT JOIN cd cds_80s ON
151 cds_80s.artist = me.artistid
152 AND cds_80s.year < ?
153 AND cds_80s.year > ?
154
155with the bind values:
156
157 '1990', '1979'
158
159C<< $args->{foreign_alias} >> and C<< $args->{self_alias} >> are supplied the
160same values that would be otherwise substituted for C<foreign> and C<self>
161in the simple hashref syntax case.
162
163The coderef is expected to return a valid L<SQL::Abstract> query-structure, just
164like what one would supply as the first argument to
165L<DBIx::Class::ResultSet/search>. The return value will be passed directly to
166L<SQL::Abstract> and the resulting SQL will be used verbatim as the C<ON>
167clause of the C<JOIN> statement associated with this relationship.
168
169While every coderef-based condition must return a valid C<ON> clause, it may
170elect to additionally return a simplified join-free condition hashref when
171invoked as C<< $row_object->relationship >>, as opposed to
172C<< $rs->related_resultset('relationship') >>. In this case C<$row_object> is
173passed to the coderef as C<< $args->{self_rowobj} >>, so a user can do the
174following:
175
176 sub {
177 my $args = shift;
178
179 return (
180 {
181 "$args->{foreign_alias}.artist" => { -ident => "$args->{self_alias}.artistid" },
182 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
183 },
184 $args->{self_rowobj} && {
185 "$args->{foreign_alias}.artist" => $args->{self_rowobj}->artistid,
186 "$args->{foreign_alias}.year" => { '>', "1979", '<', "1990" },
187 },
188 );
189 }
190
191Now this code:
192
193 my $artist = $schema->resultset("Artist")->find({ id => 4 });
194 $artist->cds_80s->all;
195
196Can skip a C<JOIN> altogether and instead produce:
197
198 SELECT cds_80s.cdid, cds_80s.artist, cds_80s.title, cds_80s.year, cds_80s.genreid, cds_80s.single_track
199 FROM cd cds_80s
200 WHERE cds_80s.artist = ?
201 AND cds_80s.year < ?
202 AND cds_80s.year > ?
203
204With the bind values:
205
206 '4', '1990', '1979'
207
208Note that in order to be able to use
209L<< $row->create_related|DBIx::Class::Relationship::Base/create_related >>,
210the coderef must not only return as its second such a "simple" condition
211hashref which does not depend on joins being available, but the hashref must
212contain only plain values/deflatable objects, such that the result can be
213passed directly to L<DBIx::Class::Relationship::Base/set_from_related>. For
214instance the C<year> constraint in the above example prevents the relationship
215from being used to to create related objects (an exception will be thrown).
216
217In order to allow the user to go truly crazy when generating a custom C<ON>
218clause, the C<$args> hashref passed to the subroutine contains some extra
219metadata. Currently the supplied coderef is executed as:
220
221 $relationship_info->{cond}->({
222 self_alias => The alias of the invoking resultset ('me' in case of a row object),
223 foreign_alias => The alias of the to-be-joined resultset (often matches relname),
224 self_resultsource => The invocant's resultsource,
225 foreign_relname => The relationship name (does *not* always match foreign_alias),
226 self_rowobj => The invocant itself in case of $row_obj->relationship
227 });
228
229=head3 attributes
230
231The L<standard ResultSet attributes|DBIx::Class::ResultSet/ATTRIBUTES> may
232be used as relationship attributes. In particular, the 'where' attribute is
233useful for filtering relationships:
234
235 __PACKAGE__->has_many( 'valid_users', 'MyApp::Schema::User',
236 { 'foreign.user_id' => 'self.user_id' },
237 { where => { valid => 1 } }
238 );
239
240The following attributes are also valid:
241
242=over 4
243
244=item join_type
245
246Explicitly specifies the type of join to use in the relationship. Any SQL
247join type is valid, e.g. C<LEFT> or C<RIGHT>. It will be placed in the SQL
248command immediately before C<JOIN>.
249
250=item proxy =E<gt> $column | \@columns | \%column
251
252=over 4
253
254=item \@columns
255
256An arrayref containing a list of accessors in the foreign class to create in
257the main class. If, for example, you do the following:
258
259 MyApp::Schema::CD->might_have(liner_notes => 'MyApp::Schema::LinerNotes',
260 undef, {
261 proxy => [ qw/notes/ ],
262 });
263
264Then, assuming MyApp::Schema::LinerNotes has an accessor named notes, you can do:
265
266 my $cd = MyApp::Schema::CD->find(1);
267 $cd->notes('Notes go here'); # set notes -- LinerNotes object is
268 # created if it doesn't exist
269
270=item \%column
271
272A hashref where each key is the accessor you want installed in the main class,
273and its value is the name of the original in the fireign class.
274
275 MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', {
276 proxy => { cd_title => 'title' },
277 });
278
279This will create an accessor named C<cd_title> on the C<$track> row object.
280
281=back
282
283NOTE: you can pass a nested struct too, for example:
284
285 MyApp::Schema::Track->belongs_to( cd => 'DBICTest::Schema::CD', 'cd', {
286 proxy => [ 'year', { cd_title => 'title' } ],
287 });
288
289=item accessor
290
291Specifies the type of accessor that should be created for the relationship.
292Valid values are C<single> (for when there is only a single related object),
293C<multi> (when there can be many), and C<filter> (for when there is a single
294related object, but you also want the relationship accessor to double as
295a column accessor). For C<multi> accessors, an add_to_* method is also
296created, which calls C<create_related> for the relationship.
297
298=item is_foreign_key_constraint
299
300If you are using L<SQL::Translator> to create SQL for you and you find that it
301is creating constraints where it shouldn't, or not creating them where it
302should, set this attribute to a true or false value to override the detection
303of when to create constraints.
304
305=item cascade_copy
306
307If C<cascade_copy> is true on a C<has_many> relationship for an
308object, then when you copy the object all the related objects will
309be copied too. To turn this behaviour off, pass C<< cascade_copy => 0 >>
310in the C<$attr> hashref.
311
312The behaviour defaults to C<< cascade_copy => 1 >> for C<has_many>
313relationships.
314
315=item cascade_delete
316
317By default, DBIx::Class cascades deletes across C<has_many>,
318C<has_one> and C<might_have> relationships. You can disable this
319behaviour on a per-relationship basis by supplying
320C<< cascade_delete => 0 >> in the relationship attributes.
321
322The cascaded operations are performed after the requested delete,
323so if your database has a constraint on the relationship, it will
324have deleted/updated the related records or raised an exception
325before DBIx::Class gets to perform the cascaded operation.
326
327=item cascade_update
328
329By default, DBIx::Class cascades updates across C<has_one> and
330C<might_have> relationships. You can disable this behaviour on a
331per-relationship basis by supplying C<< cascade_update => 0 >> in
332the relationship attributes.
333
334This is not a RDMS style cascade update - it purely means that when
335an object has update called on it, all the related objects also
336have update called. It will not change foreign keys automatically -
337you must arrange to do this yourself.
338
339=item on_delete / on_update
340
341If you are using L<SQL::Translator> to create SQL for you, you can use these
342attributes to explicitly set the desired C<ON DELETE> or C<ON UPDATE> constraint
343type. If not supplied the SQLT parser will attempt to infer the constraint type by
344interrogating the attributes of the B<opposite> relationship. For any 'multi'
345relationship with C<< cascade_delete => 1 >>, the corresponding belongs_to
346relationship will be created with an C<ON DELETE CASCADE> constraint. For any
347relationship bearing C<< cascade_copy => 1 >> the resulting belongs_to constraint
348will be C<ON UPDATE CASCADE>. If you wish to disable this autodetection, and just
349use the RDBMS' default constraint type, pass C<< on_delete => undef >> or
350C<< on_delete => '' >>, and the same for C<on_update> respectively.
351
352=item is_deferrable
353
354Tells L<SQL::Translator> that the foreign key constraint it creates should be
355deferrable. In other words, the user may request that the constraint be ignored
356until the end of the transaction. Currently, only the PostgreSQL producer
357actually supports this.
358
359=item add_fk_index
360
361Tells L<SQL::Translator> to add an index for this constraint. Can also be
362specified globally in the args to L<DBIx::Class::Schema/deploy> or
363L<DBIx::Class::Schema/create_ddl_dir>. Default is on, set to 0 to disable.
364
365=back
366
367=head2 register_relationship
368
369=over 4
370
371=item Arguments: $relname, $rel_info
372
373=back
374
375Registers a relationship on the class. This is called internally by
376DBIx::Class::ResultSourceProxy to set up Accessors and Proxies.
377
378=cut
379
38060121µs
# spent 48µs within DBIx::Class::Relationship::Base::register_relationship which was called 60 times, avg 803ns/call: # 60 times (48µs+0s) by DBIx::Class::Relationship::ProxyMethods::register_relationship at line 28 of mro.pm, avg 803ns/call
sub register_relationship { }
381
382=head2 related_resultset
383
384=over 4
385
386=item Arguments: $relationship_name
387
388=item Return Value: $related_resultset
389
390=back
391
392 $rs = $cd->related_resultset('artist');
393
394Returns a L<DBIx::Class::ResultSet> for the relationship named
395$relationship_name.
396
397=cut
398
399
# spent 2.35s (258ms+2.10) within DBIx::Class::Relationship::Base::related_resultset which was called 5440 times, avg 433µs/call: # 5440 times (258ms+2.10s) by DBIx::Class::Relationship::Base::search_related at line 512, avg 433µs/call
sub related_resultset {
40078543220ms my $self = shift;
401 $self->throw_exception("Can't call *_related as class methods")
402 unless ref $self;
403 my $rel = shift;
4045440276ms my $rel_info = $self->relationship_info($rel);
# spent 276ms making 5440 calls to DBIx::Class::ResultSourceProxy::relationship_info, avg 51µs/call
405 $self->throw_exception( "No such relationship ${rel}" )
406 unless $rel_info;
407
40818.54ms19095.01ms return $self->{related_resultsets}{$rel} ||= do {
# spent 5.01ms making 1909 calls to DBIx::Class::ResultSet::_bool, avg 3µs/call
409 my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
410 $attrs = { %{$rel_info->{attrs} || {}}, %$attrs };
411
412 $self->throw_exception( "Invalid query: @_" )
413 if (@_ > 1 && (@_ % 2 == 1));
414 my $query = ((@_ > 1) ? {@_} : shift);
415
416353110.7ms my $source = $self->result_source;
# spent 10.7ms making 3531 calls to DBIx::Class::Row::result_source, avg 3µs/call
417
418 # condition resolution may fail if an incomplete master-object prefetch
419 # is encountered - that is ok during prefetch construction (not yet in_storage)
420
# spent 147ms (18.3+128) within DBIx::Class::Relationship::Base::__ANON__[/2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/Relationship/Base.pm:422] which was called 3531 times, avg 42µs/call: # 3531 times (18.3ms+128ms) by Try::Tiny::try at line 71 of Try/Tiny.pm, avg 42µs/call
my ($cond, $is_crosstable) = try {
421353119.8ms3531128ms $source->_resolve_condition( $rel_info->{cond}, $rel, $self, $rel )
# spent 128ms making 3531 calls to DBIx::Class::ResultSource::_resolve_condition, avg 36µs/call
422 }
423 catch {
424 if ($self->in_storage) {
425 $self->throw_exception ($_);
426 }
427
428 $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION; # RV
4297062221ms };
# spent 202ms making 3531 calls to Try::Tiny::try, avg 57µs/call # spent 19.8ms making 3531 calls to Try::Tiny::catch, avg 6µs/call
430
431 # keep in mind that the following if() block is part of a do{} - no return()s!!!
432 if ($is_crosstable) {
433 $self->throw_exception (
434 "A cross-table relationship condition returned for statically declared '$rel'")
435 unless ref $rel_info->{cond} eq 'CODE';
436
437 # A WHOREIFFIC hack to reinvoke the entire condition resolution
438 # with the correct alias. Another way of doing this involves a
439 # lot of state passing around, and the @_ positions are already
440 # mapped out, making this crap a less icky option.
441 #
442 # The point of this exercise is to retain the spirit of the original
443 # $obj->search_related($rel) where the resulting rset will have the
444 # root alias as 'me', instead of $rel (as opposed to invoking
445 # $rs->search_related)
446
447 local $source->{_relationships}{me} = $source->{_relationships}{$rel}; # make the fake 'me' rel
448 my $obj_table_alias = lc($source->source_name) . '__row';
449 $obj_table_alias =~ s/\W+/_/g;
450
451 $source->resultset->search(
452 $self->ident_condition($obj_table_alias),
453 { alias => $obj_table_alias },
454 )->search_related('me', $query, $attrs)
455 }
456 else {
457 # FIXME - this conditional doesn't seem correct - got to figure out
458 # at some point what it does. Also the entire UNRESOLVABLE_CONDITION
459 # business seems shady - we could simply not query *at all*
460 if ($cond eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION) {
461 my $reverse = $source->reverse_relationship_info($rel);
462 foreach my $rev_rel (keys %$reverse) {
463 if ($reverse->{$rev_rel}{attrs}{accessor} && $reverse->{$rev_rel}{attrs}{accessor} eq 'multi') {
464 $attrs->{related_objects}{$rev_rel} = [ $self ];
465 weaken $attrs->{related_object}{$rev_rel}[0];
466 } else {
467 $attrs->{related_objects}{$rev_rel} = $self;
468 weaken $attrs->{related_object}{$rev_rel};
469 }
470 }
471 }
472 elsif (ref $cond eq 'ARRAY') {
473 $cond = [ map {
474 if (ref $_ eq 'HASH') {
475 my $hash;
476 foreach my $key (keys %$_) {
477 my $newkey = $key !~ /\./ ? "me.$key" : $key;
478 $hash->{$newkey} = $_->{$key};
479 }
480 $hash;
481 } else {
482 $_;
483 }
484 } @$cond ];
485 }
486 elsif (ref $cond eq 'HASH') {
48735314.60ms foreach my $key (grep { ! /\./ } keys %$cond) {
# spent 4.60ms making 3531 calls to DBIx::Class::Relationship::Base::CORE:match, avg 1µs/call
488 $cond->{"me.$key"} = delete $cond->{$key};
489 }
490 }
491
492 $query = ($query ? { '-and' => [ $cond, $query ] } : $cond);
493141241.58s $self->result_source->related_source($rel)->resultset->search(
# spent 645ms making 3531 calls to DBIx::Class::ResultSource::resultset, avg 183µs/call # spent 628ms making 3531 calls to DBIx::Class::ResultSet::search, avg 178µs/call # spent 299ms making 3531 calls to DBIx::Class::ResultSource::related_source, avg 85µs/call # spent 6.48ms making 3531 calls to DBIx::Class::Row::result_source, avg 2µs/call
494 $query, $attrs
495 );
496 }
497 };
498}
499
500=head2 search_related
501
502 @objects = $rs->search_related('relname', $cond, $attrs);
503 $objects_rs = $rs->search_related('relname', $cond, $attrs);
504
505Run a search on a related resultset. The search will be restricted to the
506item or items represented by the L<DBIx::Class::ResultSet> it was called
507upon. This method can be called on a ResultSet, a Row or a ResultSource class.
508
509=cut
510
511
# spent 3.72s (54.1ms+3.67) within DBIx::Class::Relationship::Base::search_related which was called 5440 times, avg 684µs/call: # 3639 times (35.6ms+2.36s) by Tapper::Schema::TestrunDB::Result::Host::features or Tapper::Schema::TestrunDB::Result::Host::queuehosts or Tapper::Schema::TestrunDB::Result::Queue::testrunschedulings or Tapper::Schema::TestrunDB::Result::TestrunScheduling::requested_features or Tapper::Schema::TestrunDB::Result::TestrunScheduling::requested_hosts at line 65 of DBIx/Class/Relationship/Accessor.pm, avg 658µs/call # 1654 times (17.2ms+1.19s) by DBIx::Class::Relationship::Base::find_related at line 621, avg 730µs/call # 147 times (1.35ms+119ms) by Tapper::Schema::TestrunDB::Result::Testrun::preconditions_rs at line 68 of DBIx/Class/Relationship/ManyToMany.pm, avg 818µs/call
sub search_related {
512544049.4ms112113.67s return shift->related_resultset(shift)->search(@_);
# spent 2.35s making 5440 calls to DBIx::Class::Relationship::Base::related_resultset, avg 433µs/call # spent 1.32s making 5440 calls to DBIx::Class::ResultSet::search, avg 242µs/call # spent 1.77ms making 331 calls to DBIx::Class::Storage::DBI::Cursor::DESTROY, avg 5µs/call
513}
514
515=head2 search_related_rs
516
517 ( $objects_rs ) = $rs->search_related_rs('relname', $cond, $attrs);
518
519This method works exactly the same as search_related, except that
520it guarantees a resultset, even in list context.
521
522=cut
523
524sub search_related_rs {
525 return shift->related_resultset(shift)->search_rs(@_);
526}
527
528=head2 count_related
529
530 $obj->count_related('relname', $cond, $attrs);
531
532Returns the count of all the items in the related resultset, restricted by the
533current item or where conditions. Can be called on a
534L<DBIx::Class::Manual::Glossary/"ResultSet"> or a
535L<DBIx::Class::Manual::Glossary/"Row"> object.
536
537=cut
538
539sub count_related {
540 my $self = shift;
541 return $self->search_related(@_)->count;
542}
543
544=head2 new_related
545
546 my $new_obj = $obj->new_related('relname', \%col_data);
547
548Create a new item of the related foreign class. If called on a
549L<Row|DBIx::Class::Manual::Glossary/"Row"> object, it will magically
550set any foreign key columns of the new object to the related primary
551key columns of the source object for you. The newly created item will
552not be saved into your storage until you call L<DBIx::Class::Row/insert>
553on it.
554
555=cut
556
557sub new_related {
558 my ($self, $rel, $values, $attrs) = @_;
559
560 # FIXME - this is a bad position for this (also an identical copy in
561 # set_from_related), but I have no saner way to hook, and I absolutely
562 # want this to throw at least for coderefs, instead of the "insert a NULL
563 # when it gets hard" insanity --ribasushi
564 #
565 # sanity check - currently throw when a complex coderef rel is encountered
566 # FIXME - should THROW MOAR!
567
568 if (ref $self) { # cdbi calls this as a class method, /me vomits
569
570 my $rsrc = $self->result_source;
571 my (undef, $crosstable, $relcols) = $rsrc->_resolve_condition (
572 $rsrc->relationship_info($rel)->{cond}, $rel, $self, $rel
573 );
574
575 $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")
576 if $crosstable;
577
578 if (@{$relcols || []} and @$relcols = grep { ! exists $values->{$_} } @$relcols) {
579 $self->throw_exception(sprintf (
580 "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
581 $rel,
582 map { "'$_'" } @$relcols
583 ));
584 }
585 }
586
587 my $row = $self->search_related($rel)->new($values, $attrs);
588 return $row;
589}
590
591=head2 create_related
592
593 my $new_obj = $obj->create_related('relname', \%col_data);
594
595Creates a new item, similarly to new_related, and also inserts the item's data
596into your storage medium. See the distinction between C<create> and C<new>
597in L<DBIx::Class::ResultSet> for details.
598
599=cut
600
601sub create_related {
602 my $self = shift;
603 my $rel = shift;
604 my $obj = $self->new_related($rel, @_)->insert;
605 delete $self->{related_resultsets}->{$rel};
606 return $obj;
607}
608
609=head2 find_related
610
611 my $found_item = $obj->find_related('relname', @pri_vals | \%pri_vals);
612
613Attempt to find a related object using its primary key or unique constraints.
614See L<DBIx::Class::ResultSet/find> for details.
615
616=cut
617
618
# spent 5.20s (24.1ms+5.18) within DBIx::Class::Relationship::Base::find_related which was called 1654 times, avg 3.14ms/call: # 1654 times (24.1ms+5.18s) by Tapper::Schema::TestrunDB::Result::QueueHost::queue or Tapper::Schema::TestrunDB::Result::Testrun::scenario_element or Tapper::Schema::TestrunDB::Result::TestrunScheduling::host or Tapper::Schema::TestrunDB::Result::TestrunScheduling::queue or Tapper::Schema::TestrunDB::Result::TestrunScheduling::testrun at line 41 of DBIx/Class/Relationship/Accessor.pm, avg 3.14ms/call
sub find_related {
619496220.7ms my $self = shift;
620 my $rel = shift;
62133085.18s return $self->search_related($rel)->find(@_);
# spent 3.97s making 1654 calls to DBIx::Class::ResultSet::find, avg 2.40ms/call # spent 1.21s making 1654 calls to DBIx::Class::Relationship::Base::search_related, avg 730µs/call
622}
623
624=head2 find_or_new_related
625
626 my $new_obj = $obj->find_or_new_related('relname', \%col_data);
627
628Find an item of a related class. If none exists, instantiate a new item of the
629related class. The object will not be saved into your storage until you call
630L<DBIx::Class::Row/insert> on it.
631
632=cut
633
634sub find_or_new_related {
635 my $self = shift;
636 my $obj = $self->find_related(@_);
637 return defined $obj ? $obj : $self->new_related(@_);
638}
639
640=head2 find_or_create_related
641
642 my $new_obj = $obj->find_or_create_related('relname', \%col_data);
643
644Find or create an item of a related class. See
645L<DBIx::Class::ResultSet/find_or_create> for details.
646
647=cut
648
649sub find_or_create_related {
650 my $self = shift;
651 my $obj = $self->find_related(@_);
652 return (defined($obj) ? $obj : $self->create_related(@_));
653}
654
655=head2 update_or_create_related
656
657 my $updated_item = $obj->update_or_create_related('relname', \%col_data, \%attrs?);
658
659Update or create an item of a related class. See
660L<DBIx::Class::ResultSet/update_or_create> for details.
661
662=cut
663
664sub update_or_create_related {
665 my $self = shift;
666 my $rel = shift;
667 return $self->related_resultset($rel)->update_or_create(@_);
668}
669
670=head2 set_from_related
671
672 $book->set_from_related('author', $author_obj);
673 $book->author($author_obj); ## same thing
674
675Set column values on the current object, using related values from the given
676related object. This is used to associate previously separate objects, for
677example, to set the correct author for a book, find the Author object, then
678call set_from_related on the book.
679
680This is called internally when you pass existing objects as values to
681L<DBIx::Class::ResultSet/create>, or pass an object to a belongs_to accessor.
682
683The columns are only set in the local copy of the object, call L</update> to
684set them in the storage.
685
686=cut
687
688sub set_from_related {
689 my ($self, $rel, $f_obj) = @_;
690
691 my $rsrc = $self->result_source;
692 my $rel_info = $rsrc->relationship_info($rel)
693 or $self->throw_exception( "No such relationship ${rel}" );
694
695 if (defined $f_obj) {
696 my $f_class = $rel_info->{class};
697 $self->throw_exception( "Object $f_obj isn't a ".$f_class )
698 unless blessed $f_obj and $f_obj->isa($f_class);
699 }
700
701
702 # FIXME - this is a bad position for this (also an identical copy in
703 # new_related), but I have no saner way to hook, and I absolutely
704 # want this to throw at least for coderefs, instead of the "insert a NULL
705 # when it gets hard" insanity --ribasushi
706 #
707 # sanity check - currently throw when a complex coderef rel is encountered
708 # FIXME - should THROW MOAR!
709 my ($cond, $crosstable, $relcols) = $rsrc->_resolve_condition (
710 $rel_info->{cond}, $f_obj, $rel, $rel
711 );
712 $self->throw_exception("Custom relationship '$rel' does not resolve to a join-free condition fragment")
713 if $crosstable;
714 $self->throw_exception(sprintf (
715 "Custom relationship '%s' not definitive - returns conditions instead of values for column(s): %s",
716 $rel,
717 map { "'$_'" } @$relcols
718 )) if @{$relcols || []};
719
720 $self->set_columns($cond);
721
722 return 1;
723}
724
725=head2 update_from_related
726
727 $book->update_from_related('author', $author_obj);
728
729The same as L</"set_from_related">, but the changes are immediately updated
730in storage.
731
732=cut
733
734sub update_from_related {
735 my $self = shift;
736 $self->set_from_related(@_);
737 $self->update;
738}
739
740=head2 delete_related
741
742 $obj->delete_related('relname', $cond, $attrs);
743
744Delete any related item subject to the given conditions.
745
746=cut
747
748sub delete_related {
749 my $self = shift;
750 my $obj = $self->search_related(@_)->delete;
751 delete $self->{related_resultsets}->{$_[0]};
752 return $obj;
753}
754
755=head2 add_to_$rel
756
757B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
758relationships.>
759
760=over 4
761
762=item Arguments: ($foreign_vals | $obj), $link_vals?
763
764=back
765
766 my $role = $schema->resultset('Role')->find(1);
767 $actor->add_to_roles($role);
768 # creates a My::DBIC::Schema::ActorRoles linking table row object
769
770 $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
771 # creates a new My::DBIC::Schema::Role row object and the linking table
772 # object with an extra column in the link
773
774Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
775argument is a hash reference, the related object is created first with the
776column values in the hash. If an object reference is given, just the linking
777table object is created. In either case, any additional column values for the
778linking table object can be specified in C<$link_vals>.
779
780=head2 set_$rel
781
782B<Currently only available for C<many-to-many> relationships.>
783
784=over 4
785
786=item Arguments: (\@hashrefs | \@objs), $link_vals?
787
788=back
789
790 my $actor = $schema->resultset('Actor')->find(1);
791 my @roles = $schema->resultset('Role')->search({ role =>
792 { '-in' => ['Fred', 'Barney'] } } );
793
794 $actor->set_roles(\@roles);
795 # Replaces all of $actor's previous roles with the two named
796
797 $actor->set_roles(\@roles, { salary => 15_000_000 });
798 # Sets a column in the link table for all roles
799
800
801Replace all the related objects with the given reference to a list of
802objects. This does a C<delete> B<on the link table resultset> to remove the
803association between the current object and all related objects, then calls
804C<add_to_$rel> repeatedly to link all the new objects.
805
806Note that this means that this method will B<not> delete any objects in the
807table on the right side of the relation, merely that it will delete the link
808between them.
809
810Due to a mistake in the original implementation of this method, it will also
811accept a list of objects or hash references. This is B<deprecated> and will be
812removed in a future version.
813
814=head2 remove_from_$rel
815
816B<Currently only available for C<many-to-many> relationships.>
817
818=over 4
819
820=item Arguments: $obj
821
822=back
823
824 my $role = $schema->resultset('Role')->find(1);
825 $actor->remove_from_roles($role);
826 # removes $role's My::DBIC::Schema::ActorRoles linking table row object
827
828Removes the link between the current object and the related object. Note that
829the related object itself won't be deleted unless you call ->delete() on
830it. This method just removes the link between the two objects.
831
832=head1 AUTHORS
833
834Matt S. Trout <mst@shadowcatsystems.co.uk>
835
836=head1 LICENSE
837
838You may distribute this code under the same terms as Perl itself.
839
840=cut
841
84219µs1308µs1;
 
# spent 4.60ms within DBIx::Class::Relationship::Base::CORE:match which was called 3531 times, avg 1µs/call: # 3531 times (4.60ms+0s) by DBIx::Class::Relationship::Base::related_resultset at line 487, avg 1µs/call
sub DBIx::Class::Relationship::Base::CORE:match; # opcode