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