sqlt parser now respected a relationship attribute of is_foreign_key_constraint
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Relationship / Base.pm
1 package DBIx::Class::Relationship::Base;
2
3 use strict;
4 use warnings;
5
6 use Scalar::Util ();
7 use base qw/DBIx::Class/;
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 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
328 Set column values on the current object, using related values from the given
329 related object. This is used to associate previously separate objects, for
330 example, to set the correct author for a book, find the Author object, then
331 call set_from_related on the book.
332
333 The columns are only set in the local copy of the object, call L</update> to
334 set them in the storage.
335
336 =cut
337
338 sub set_from_related {
339   my ($self, $rel, $f_obj) = @_;
340   my $rel_obj = $self->relationship_info($rel);
341   $self->throw_exception( "No such relationship ${rel}" ) unless $rel_obj;
342   my $cond = $rel_obj->{cond};
343   $self->throw_exception(
344     "set_from_related can only handle a hash condition; the ".
345     "condition for $rel is of type ".
346     (ref $cond ? ref $cond : 'plain scalar')
347   ) unless ref $cond eq 'HASH';
348   if (defined $f_obj) {
349     my $f_class = $self->result_source->schema->class($rel_obj->{class});
350     $self->throw_exception( "Object $f_obj isn't a ".$f_class )
351       unless Scalar::Util::blessed($f_obj) and $f_obj->isa($f_class);
352   }
353   $self->set_columns(
354     $self->result_source->resolve_condition(
355        $rel_obj->{cond}, $f_obj, $rel));
356   return 1;
357 }
358
359 =head2 update_from_related
360
361   $book->update_from_related('author', $author_obj);
362
363 The same as L</"set_from_related">, but the changes are immediately updated
364 in storage.
365
366 =cut
367
368 sub update_from_related {
369   my $self = shift;
370   $self->set_from_related(@_);
371   $self->update;
372 }
373
374 =head2 delete_related
375
376   $obj->delete_related('relname', $cond, $attrs);
377
378 Delete any related item subject to the given conditions.
379
380 =cut
381
382 sub delete_related {
383   my $self = shift;
384   my $obj = $self->search_related(@_)->delete;
385   delete $self->{related_resultsets}->{$_[0]};
386   return $obj;
387 }
388
389 =head2 add_to_$rel
390
391 B<Currently only available for C<has_many>, C<many-to-many> and 'multi' type
392 relationships.>
393
394 =over 4
395
396 =item Arguments: ($foreign_vals | $obj), $link_vals?
397
398 =back
399
400   my $role = $schema->resultset('Role')->find(1);
401   $actor->add_to_roles($role);
402       # creates a My::DBIC::Schema::ActorRoles linking table row object
403
404   $actor->add_to_roles({ name => 'lead' }, { salary => 15_000_000 });
405       # creates a new My::DBIC::Schema::Role row object and the linking table
406       # object with an extra column in the link
407
408 Adds a linking table object for C<$obj> or C<$foreign_vals>. If the first
409 argument is a hash reference, the related object is created first with the
410 column values in the hash. If an object reference is given, just the linking
411 table object is created. In either case, any additional column values for the
412 linking table object can be specified in C<$link_vals>.
413
414 =head2 set_$rel
415
416 B<Currently only available for C<many-to-many> relationships.>
417
418 =over 4
419
420 =item Arguments: (\@hashrefs | \@objs)
421
422 =back
423
424   my $actor = $schema->resultset('Actor')->find(1);
425   my @roles = $schema->resultset('Role')->search({ role => 
426      { '-in' -> ['Fred', 'Barney'] } } );
427
428   $actor->set_roles(\@roles);
429      # Replaces all of $actor's previous roles with the two named
430
431 Replace all the related objects with the given reference to a list of
432 objects. This does a C<delete> B<on the link table resultset> to remove the
433 association between the current object and all related objects, then calls
434 C<add_to_$rel> repeatedly to link all the new objects.
435
436 Note that this means that this method will B<not> delete any objects in the
437 table on the right side of the relation, merely that it will delete the link
438 between them.
439
440 Due to a mistake in the original implementation of this method, it will also
441 accept a list of objects or hash references. This is B<deprecated> and will be
442 removed in a future version.
443
444 =head2 remove_from_$rel
445
446 B<Currently only available for C<many-to-many> relationships.>
447
448 =over 4
449
450 =item Arguments: $obj
451
452 =back
453
454   my $role = $schema->resultset('Role')->find(1);
455   $actor->remove_from_roles($role);
456       # removes $role's My::DBIC::Schema::ActorRoles linking table row object
457
458 Removes the link between the current object and the related object. Note that
459 the related object itself won't be deleted unless you call ->delete() on
460 it. This method just removes the link between the two objects.
461
462 =head1 AUTHORS
463
464 Matt S. Trout <mst@shadowcatsystems.co.uk>
465
466 =head1 LICENSE
467
468 You may distribute this code under the same terms as Perl itself.
469
470 =cut
471
472 1;