More indirect call removals: the second part of 77c3a5dc
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
1 package DBIx::Class::Row;
2
3 use strict;
4 use warnings;
5
6 use base qw/DBIx::Class/;
7
8 use Scalar::Util 'blessed';
9 use DBIx::Class::_Util qw( dbic_internal_try fail_on_internal_call );
10 use DBIx::Class::Carp;
11 use SQL::Abstract qw( is_literal_value is_plain_value );
12
13 ###
14 ### Internal method
15 ### Do not use
16 ###
17 BEGIN {
18   *MULTICREATE_DEBUG =
19     $ENV{DBIC_MULTICREATE_DEBUG}
20       ? sub () { 1 }
21       : sub () { 0 };
22 }
23
24 use namespace::clean;
25
26 __PACKAGE__->mk_group_accessors ( simple => [ in_storage => '_in_storage' ] );
27
28 =head1 NAME
29
30 DBIx::Class::Row - Basic row methods
31
32 =head1 SYNOPSIS
33
34 =head1 DESCRIPTION
35
36 This class is responsible for defining and doing basic operations on rows
37 derived from L<DBIx::Class::ResultSource> objects.
38
39 Result objects are returned from L<DBIx::Class::ResultSet>s using the
40 L<create|DBIx::Class::ResultSet/create>, L<find|DBIx::Class::ResultSet/find>,
41 L<next|DBIx::Class::ResultSet/next> and L<all|DBIx::Class::ResultSet/all> methods,
42 as well as invocations of 'single' (
43 L<belongs_to|DBIx::Class::Relationship/belongs_to>,
44 L<has_one|DBIx::Class::Relationship/has_one> or
45 L<might_have|DBIx::Class::Relationship/might_have>)
46 relationship accessors of L<Result|DBIx::Class::Manual::ResultClass> objects.
47
48 =head1 NOTE
49
50 All "Row objects" derived from a Schema-attached L<DBIx::Class::ResultSet>
51 object (such as a typical C<< L<search|DBIx::Class::ResultSet/search>->
52 L<next|DBIx::Class::ResultSet/next> >> call) are actually Result
53 instances, based on your application's
54 L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
55
56 L<DBIx::Class::Row> implements most of the row-based communication with the
57 underlying storage, but a Result class B<should not inherit from it directly>.
58 Usually, Result classes inherit from L<DBIx::Class::Core>, which in turn
59 combines the methods from several classes, one of them being
60 L<DBIx::Class::Row>.  Therefore, while many of the methods available to a
61 L<DBIx::Class::Core>-derived Result class are described in the following
62 documentation, it does not detail all of the methods available to Result
63 objects.  Refer to L<DBIx::Class::Manual::ResultClass> for more info.
64
65 =head1 METHODS
66
67 =head2 new
68
69   my $result = My::Class->new(\%attrs);
70
71   my $result = $schema->resultset('MySource')->new(\%colsandvalues);
72
73 =over
74
75 =item Arguments: \%attrs or \%colsandvalues
76
77 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
78
79 =back
80
81 While you can create a new result object by calling C<new> directly on
82 this class, you are better off calling it on a
83 L<DBIx::Class::ResultSet> object.
84
85 When calling it directly, you will not get a complete, usable row
86 object until you pass or set the C<result_source> attribute, to a
87 L<DBIx::Class::ResultSource> instance that is attached to a
88 L<DBIx::Class::Schema> with a valid connection.
89
90 C<$attrs> is a hashref of column name, value data. It can also contain
91 some other attributes such as the C<result_source>.
92
93 Passing an object, or an arrayref of objects as a value will call
94 L<DBIx::Class::Relationship::Base/set_from_related> for you. When
95 passed a hashref or an arrayref of hashrefs as the value, these will
96 be turned into objects via new_related, and treated as if you had
97 passed objects.
98
99 For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
100
101 Please note that if a value is not passed to new, no value will be sent
102 in the SQL INSERT call, and the column will therefore assume whatever
103 default value was specified in your database. While DBIC will retrieve the
104 value of autoincrement columns, it will never make an explicit database
105 trip to retrieve default values assigned by the RDBMS. You can explicitly
106 request that all values be fetched back from the database by calling
107 L</discard_changes>, or you can supply an explicit C<undef> to columns
108 with NULL as the default, and save yourself a SELECT.
109
110  CAVEAT:
111
112  The behavior described above will backfire if you use a foreign key column
113  with a database-defined default. If you call the relationship accessor on
114  an object that doesn't have a set value for the FK column, DBIC will throw
115  an exception, as it has no way of knowing the PK of the related object (if
116  there is one).
117
118 =cut
119
120 ## It needs to store the new objects somewhere, and call insert on that list later when insert is called on this object. We may need an accessor for these so the user can retrieve them, if just doing ->new().
121 ## This only works because DBIC doesn't yet care to check whether the new_related objects have been passed all their mandatory columns
122 ## When doing the later insert, we need to make sure the PKs are set.
123 ## using _relationship_data in new and funky ways..
124 ## check Relationship::CascadeActions and Relationship::Accessor for compat
125 ## tests!
126
127 sub __new_related_find_or_new_helper {
128   my ($self, $rel_name, $values) = @_;
129
130   my $rsrc = $self->result_source;
131
132   # create a mock-object so all new/set_column component overrides will run:
133   my $rel_rs = $rsrc->related_source($rel_name)->resultset;
134   my $new_rel_obj = $rel_rs->new_result($values);
135   my $proc_data = { $new_rel_obj->get_columns };
136
137   if ($self->__their_pk_needs_us($rel_name)) {
138     MULTICREATE_DEBUG and print STDERR "MC $self constructing $rel_name via new_result\n";
139     return $new_rel_obj;
140   }
141   elsif ($rsrc->_pk_depends_on($rel_name, $proc_data )) {
142     if (! keys %$proc_data) {
143       # there is nothing to search for - blind create
144       MULTICREATE_DEBUG and print STDERR "MC $self constructing default-insert $rel_name\n";
145     }
146     else {
147       MULTICREATE_DEBUG and print STDERR "MC $self constructing $rel_name via find_or_new\n";
148       # this is not *really* find or new, as we don't want to double-new the
149       # data (thus potentially double encoding or whatever)
150       my $exists = $rel_rs->find ($proc_data);
151       return $exists if $exists;
152     }
153     return $new_rel_obj;
154   }
155   else {
156     my $us = $rsrc->source_name;
157     $self->throw_exception (
158       "Unable to determine relationship '$rel_name' direction from '$us', "
159     . "possibly due to a missing reverse-relationship on '$rel_name' to '$us'."
160     );
161   }
162 }
163
164 sub __their_pk_needs_us { # this should maybe be in resultsource.
165   my ($self, $rel_name) = @_;
166   my $rsrc = $self->result_source;
167   my $reverse = $rsrc->reverse_relationship_info($rel_name);
168   my $rel_source = $rsrc->related_source($rel_name);
169   my $us = { $self->get_columns };
170   foreach my $key (keys %$reverse) {
171     # if their primary key depends on us, then we have to
172     # just create a result and we'll fill it out afterwards
173     return 1 if $rel_source->_pk_depends_on($key, $us);
174   }
175   return 0;
176 }
177
178 sub new {
179   my ($class, $attrs) = @_;
180   $class = ref $class if ref $class;
181
182   my $new = bless { _column_data => {}, _in_storage => 0 }, $class;
183
184   if ($attrs) {
185     $new->throw_exception("attrs must be a hashref")
186       unless ref($attrs) eq 'HASH';
187
188     my $rsrc = delete $attrs->{-result_source};
189     if ( my $h = delete $attrs->{-source_handle} ) {
190       $rsrc ||= $h->resolve;
191     }
192
193     $new->result_source($rsrc) if $rsrc;
194
195     if (my $col_from_rel = delete $attrs->{-cols_from_relations}) {
196       @{$new->{_ignore_at_insert}={}}{@$col_from_rel} = ();
197     }
198
199     my ($related,$inflated);
200
201     foreach my $key (keys %$attrs) {
202       if (ref $attrs->{$key} and ! is_literal_value($attrs->{$key}) ) {
203         ## Can we extract this lot to use with update(_or .. ) ?
204         $new->throw_exception("Can't do multi-create without result source")
205           unless $rsrc;
206         my $info = $rsrc->relationship_info($key);
207         my $acc_type = $info->{attrs}{accessor} || '';
208         if ($acc_type eq 'single') {
209           my $rel_obj = delete $attrs->{$key};
210           if(!blessed $rel_obj) {
211             $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
212           }
213
214           if ($rel_obj->in_storage) {
215             $new->{_rel_in_storage}{$key} = 1;
216             $new->set_from_related($key, $rel_obj);
217           } else {
218             MULTICREATE_DEBUG and print STDERR "MC $new uninserted $key $rel_obj\n";
219           }
220
221           $related->{$key} = $rel_obj;
222           next;
223         }
224         elsif ($acc_type eq 'multi' && ref $attrs->{$key} eq 'ARRAY' ) {
225           my $others = delete $attrs->{$key};
226           my $total = @$others;
227           my @objects;
228           foreach my $idx (0 .. $#$others) {
229             my $rel_obj = $others->[$idx];
230             if(!blessed $rel_obj) {
231               $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
232             }
233
234             if ($rel_obj->in_storage) {
235               $rel_obj->throw_exception ('A multi relationship can not be pre-existing when doing multicreate. Something went wrong');
236             } else {
237               MULTICREATE_DEBUG and
238                 print STDERR "MC $new uninserted $key $rel_obj (${\($idx+1)} of $total)\n";
239             }
240             push(@objects, $rel_obj);
241           }
242           $related->{$key} = \@objects;
243           next;
244         }
245         elsif ($acc_type eq 'filter') {
246           ## 'filter' should disappear and get merged in with 'single' above!
247           my $rel_obj = delete $attrs->{$key};
248           if(!blessed $rel_obj) {
249             $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
250           }
251           if ($rel_obj->in_storage) {
252             $new->{_rel_in_storage}{$key} = 1;
253           }
254           else {
255             MULTICREATE_DEBUG and print STDERR "MC $new uninserted $key $rel_obj\n";
256           }
257           $inflated->{$key} = $rel_obj;
258           next;
259         }
260         elsif (
261           $rsrc->has_column($key)
262             and
263           $rsrc->column_info($key)->{_inflate_info}
264         ) {
265           $inflated->{$key} = $attrs->{$key};
266           next;
267         }
268       }
269       $new->store_column($key => $attrs->{$key});
270     }
271
272     $new->{_relationship_data} = $related if $related;
273     $new->{_inflated_column} = $inflated if $inflated;
274   }
275
276   return $new;
277 }
278
279 =head2 $column_accessor
280
281   # Each pair does the same thing
282
283   # (un-inflated, regular column)
284   my $val = $result->get_column('first_name');
285   my $val = $result->first_name;
286
287   $result->set_column('first_name' => $val);
288   $result->first_name($val);
289
290   # (inflated column via DBIx::Class::InflateColumn::DateTime)
291   my $val = $result->get_inflated_column('last_modified');
292   my $val = $result->last_modified;
293
294   $result->set_inflated_column('last_modified' => $val);
295   $result->last_modified($val);
296
297 =over
298
299 =item Arguments: $value?
300
301 =item Return Value: $value
302
303 =back
304
305 A column accessor method is created for each column, which is used for
306 getting/setting the value for that column.
307
308 The actual method name is based on the
309 L<accessor|DBIx::Class::ResultSource/accessor> name given during the
310 L<Result Class|DBIx::Class::Manual::ResultClass> L<column definition
311 |DBIx::Class::ResultSource/add_columns>. Like L</set_column>, this
312 will not store the data in the database until L</insert> or L</update>
313 is called on the row.
314
315 =head2 insert
316
317   $result->insert;
318
319 =over
320
321 =item Arguments: none
322
323 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
324
325 =back
326
327 Inserts an object previously created by L</new> into the database if
328 it isn't already in there. Returns the object itself. To insert an
329 entirely new row into the database, use L<DBIx::Class::ResultSet/create>.
330
331 To fetch an uninserted result object, call
332 L<new_result|DBIx::Class::ResultSet/new_result> on a resultset.
333
334 This will also insert any uninserted, related objects held inside this
335 one, see L<DBIx::Class::ResultSet/create> for more details.
336
337 =cut
338
339 sub insert {
340   my ($self) = @_;
341   return $self if $self->in_storage;
342   my $rsrc = $self->result_source;
343   $self->throw_exception("No result_source set on this object; can't insert")
344     unless $rsrc;
345
346   my $storage = $rsrc->schema->storage;
347
348   my $rollback_guard;
349
350   # Check if we stored uninserted relobjs here in new()
351   my %related_stuff = (%{$self->{_relationship_data} || {}},
352                        %{$self->{_inflated_column} || {}});
353
354   # insert what needs to be inserted before us
355   my %pre_insert;
356   for my $rel_name (keys %related_stuff) {
357     my $rel_obj = $related_stuff{$rel_name};
358
359     if (! $self->{_rel_in_storage}{$rel_name}) {
360       next unless (blessed $rel_obj && $rel_obj->isa('DBIx::Class::Row'));
361
362       next unless $rsrc->_pk_depends_on(
363                     $rel_name, { $rel_obj->get_columns }
364                   );
365
366       # The guard will save us if we blow out of this scope via die
367       $rollback_guard ||= $storage->txn_scope_guard;
368
369       MULTICREATE_DEBUG and print STDERR "MC $self pre-reconstructing $rel_name $rel_obj\n";
370
371       my $them = { %{$rel_obj->{_relationship_data} || {} }, $rel_obj->get_columns };
372       my $existing;
373
374       # if there are no keys - nothing to search for
375       if (keys %$them and $existing = $rsrc->related_source($rel_name)
376                                            ->resultset
377                                            ->find($them)
378       ) {
379         %{$rel_obj} = %{$existing};
380       }
381       else {
382         $rel_obj->insert;
383       }
384
385       $self->{_rel_in_storage}{$rel_name} = 1;
386     }
387
388     $self->set_from_related($rel_name, $rel_obj);
389     delete $related_stuff{$rel_name};
390   }
391
392   # start a transaction here if not started yet and there is more stuff
393   # to insert after us
394   if (keys %related_stuff) {
395     $rollback_guard ||= $storage->txn_scope_guard
396   }
397
398   MULTICREATE_DEBUG and do {
399     no warnings 'uninitialized';
400     print STDERR "MC $self inserting (".join(', ', $self->get_columns).")\n";
401   };
402
403   # perform the insert - the storage will return everything it is asked to
404   # (autoinc primary columns and any retrieve_on_insert columns)
405   my %current_rowdata = $self->get_columns;
406   my $returned_cols = $storage->insert(
407     $rsrc,
408     { %current_rowdata }, # what to insert, copy because the storage *will* change it
409   );
410
411   for (keys %$returned_cols) {
412     $self->store_column($_, $returned_cols->{$_})
413       # this ensures we fire store_column only once
414       # (some asshats like overriding it)
415       if (
416         (!exists $current_rowdata{$_})
417           or
418         (defined $current_rowdata{$_} xor defined $returned_cols->{$_})
419           or
420         (defined $current_rowdata{$_} and $current_rowdata{$_} ne $returned_cols->{$_})
421       );
422   }
423
424   delete $self->{_column_data_in_storage};
425   $self->in_storage(1);
426
427   $self->{_dirty_columns} = {};
428   $self->{related_resultsets} = {};
429
430   foreach my $rel_name (keys %related_stuff) {
431     next unless $rsrc->has_relationship ($rel_name);
432
433     my @cands = ref $related_stuff{$rel_name} eq 'ARRAY'
434       ? @{$related_stuff{$rel_name}}
435       : $related_stuff{$rel_name}
436     ;
437
438     if (@cands && blessed $cands[0] && $cands[0]->isa('DBIx::Class::Row')
439     ) {
440       my $reverse = $rsrc->reverse_relationship_info($rel_name);
441       foreach my $obj (@cands) {
442         $obj->set_from_related($_, $self) for keys %$reverse;
443         if ($self->__their_pk_needs_us($rel_name)) {
444           if (exists $self->{_ignore_at_insert}{$rel_name}) {
445             MULTICREATE_DEBUG and print STDERR "MC $self skipping post-insert on $rel_name\n";
446           }
447           else {
448             MULTICREATE_DEBUG and print STDERR "MC $self inserting $rel_name $obj\n";
449             $obj->insert;
450           }
451         } else {
452           MULTICREATE_DEBUG and print STDERR "MC $self post-inserting $obj\n";
453           $obj->insert();
454         }
455       }
456     }
457   }
458
459   delete $self->{_ignore_at_insert};
460
461   $rollback_guard->commit if $rollback_guard;
462
463   return $self;
464 }
465
466 =head2 in_storage
467
468   $result->in_storage; # Get value
469   $result->in_storage(1); # Set value
470
471 =over
472
473 =item Arguments: none or 1|0
474
475 =item Return Value: 1|0
476
477 =back
478
479 Indicates whether the object exists as a row in the database or
480 not. This is set to true when L<DBIx::Class::ResultSet/find>,
481 L<DBIx::Class::ResultSet/create> or L<DBIx::Class::Row/insert>
482 are invoked.
483
484 Creating a result object using L<DBIx::Class::ResultSet/new_result>, or
485 calling L</delete> on one, sets it to false.
486
487
488 =head2 update
489
490   $result->update(\%columns?)
491
492 =over
493
494 =item Arguments: none or a hashref
495
496 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
497
498 =back
499
500 Throws an exception if the result object is not yet in the database,
501 according to L</in_storage>. Returns the object itself.
502
503 This method issues an SQL UPDATE query to commit any changes to the
504 object to the database if required (see L</get_dirty_columns>).
505 It throws an exception if a proper WHERE clause uniquely identifying
506 the database row can not be constructed (see
507 L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
508 for more details).
509
510 Also takes an optional hashref of C<< column_name => value >> pairs
511 to update on the object first. Be aware that the hashref will be
512 passed to C<set_inflated_columns>, which might edit it in place, so
513 don't rely on it being the same after a call to C<update>.  If you
514 need to preserve the hashref, it is sufficient to pass a shallow copy
515 to C<update>, e.g. ( { %{ $href } } )
516
517 If the values passed or any of the column values set on the object
518 contain scalar references, e.g.:
519
520   $result->last_modified(\'NOW()')->update();
521   # OR
522   $result->update({ last_modified => \'NOW()' });
523
524 The update will pass the values verbatim into SQL. (See
525 L<SQL::Abstract> docs).  The values in your Result object will NOT change
526 as a result of the update call, if you want the object to be updated
527 with the actual values from the database, call L</discard_changes>
528 after the update.
529
530   $result->update()->discard_changes();
531
532 To determine before calling this method, which column values have
533 changed and will be updated, call L</get_dirty_columns>.
534
535 To check if any columns will be updated, call L</is_changed>.
536
537 To force a column to be updated, call L</make_column_dirty> before
538 this method.
539
540 =cut
541
542 sub update {
543   my ($self, $upd) = @_;
544
545   $self->set_inflated_columns($upd) if $upd;
546
547   my %to_update = $self->get_dirty_columns
548     or return $self;
549
550   $self->throw_exception( "Not in database" ) unless $self->in_storage;
551
552   my $rows = $self->result_source->schema->storage->update(
553     $self->result_source, \%to_update, $self->_storage_ident_condition
554   );
555   if ($rows == 0) {
556     $self->throw_exception( "Can't update ${self}: row not found" );
557   } elsif ($rows > 1) {
558     $self->throw_exception("Can't update ${self}: updated more than one row");
559   }
560   $self->{_dirty_columns} = {};
561   $self->{related_resultsets} = {};
562   delete $self->{_column_data_in_storage};
563   return $self;
564 }
565
566 =head2 delete
567
568   $result->delete
569
570 =over
571
572 =item Arguments: none
573
574 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
575
576 =back
577
578 Throws an exception if the object is not in the database according to
579 L</in_storage>. Also throws an exception if a proper WHERE clause
580 uniquely identifying the database row can not be constructed (see
581 L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
582 for more details).
583
584 The object is still perfectly usable, but L</in_storage> will
585 now return 0 and the object must be reinserted using L</insert>
586 before it can be used to L</update> the row again.
587
588 If you delete an object in a class with a C<has_many> relationship, an
589 attempt is made to delete all the related objects as well. To turn
590 this behaviour off, pass C<< cascade_delete => 0 >> in the C<$attr>
591 hashref of the relationship, see L<DBIx::Class::Relationship>. Any
592 database-level cascade or restrict will take precedence over a
593 DBIx-Class-based cascading delete, since DBIx-Class B<deletes the
594 main row first> and only then attempts to delete any remaining related
595 rows.
596
597 If you delete an object within a txn_do() (see L<DBIx::Class::Storage/txn_do>)
598 and the transaction subsequently fails, the result object will remain marked as
599 not being in storage. If you know for a fact that the object is still in
600 storage (i.e. by inspecting the cause of the transaction's failure), you can
601 use C<< $obj->in_storage(1) >> to restore consistency between the object and
602 the database. This would allow a subsequent C<< $obj->delete >> to work
603 as expected.
604
605 See also L<DBIx::Class::ResultSet/delete>.
606
607 =cut
608
609 sub delete {
610   my $self = shift;
611   if (ref $self) {
612     $self->throw_exception( "Not in database" ) unless $self->in_storage;
613
614     $self->result_source->schema->storage->delete(
615       $self->result_source, $self->_storage_ident_condition
616     );
617
618     delete $self->{_column_data_in_storage};
619     $self->in_storage(0);
620   }
621   else {
622     my $rsrc = dbic_internal_try { $self->result_source_instance }
623       or $self->throw_exception("Can't do class delete without a ResultSource instance");
624
625     my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? { %{pop(@_)} } : {};
626     my $query = ref $_[0] eq 'HASH' ? $_[0] : {@_};
627     $rsrc->resultset->search(@_)->delete;
628   }
629   return $self;
630 }
631
632 =head2 get_column
633
634   my $val = $result->get_column($col);
635
636 =over
637
638 =item Arguments: $columnname
639
640 =item Return Value: The value of the column
641
642 =back
643
644 Throws an exception if the column name given doesn't exist according
645 to L<has_column|DBIx::Class::ResultSource/has_column>.
646
647 Returns a raw column value from the result object, if it has already
648 been fetched from the database or set by an accessor.
649
650 If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
651 will be deflated and returned.
652
653 Note that if you used the C<columns> or the C<select/as>
654 L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
655 which C<$result> was derived, and B<did not include> C<$columnname> in the list,
656 this method will return C<undef> even if the database contains some value.
657
658 To retrieve all loaded column values as a hash, use L</get_columns>.
659
660 =cut
661
662 sub get_column {
663   my ($self, $column) = @_;
664   $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
665
666   return $self->{_column_data}{$column}
667     if exists $self->{_column_data}{$column};
668
669   if (exists $self->{_inflated_column}{$column}) {
670     # deflate+return cycle
671     return $self->store_column($column, $self->_deflated_column(
672       $column, $self->{_inflated_column}{$column}
673     ));
674   }
675
676   $self->throw_exception( "No such column '${column}' on " . ref $self )
677     unless $self->result_source->has_column($column);
678
679   return undef;
680 }
681
682 =head2 has_column_loaded
683
684   if ( $result->has_column_loaded($col) ) {
685      print "$col has been loaded from db";
686   }
687
688 =over
689
690 =item Arguments: $columnname
691
692 =item Return Value: 0|1
693
694 =back
695
696 Returns a true value if the column value has been loaded from the
697 database (or set locally).
698
699 =cut
700
701 sub has_column_loaded {
702   my ($self, $column) = @_;
703   $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
704
705   return (
706     exists $self->{_inflated_column}{$column}
707       or
708     exists $self->{_column_data}{$column}
709   ) ? 1 : 0;
710 }
711
712 =head2 get_columns
713
714   my %data = $result->get_columns;
715
716 =over
717
718 =item Arguments: none
719
720 =item Return Value: A hash of columnname, value pairs.
721
722 =back
723
724 Returns all loaded column data as a hash, containing raw values. To
725 get just one value for a particular column, use L</get_column>.
726
727 See L</get_inflated_columns> to get the inflated values.
728
729 =cut
730
731 sub get_columns {
732   my $self = shift;
733   if (exists $self->{_inflated_column}) {
734     # deflate cycle for each inflation, including filter rels
735     foreach my $col (keys %{$self->{_inflated_column}}) {
736       unless (exists $self->{_column_data}{$col}) {
737
738         # if cached related_resultset is present assume this was a prefetch
739         carp_unique(
740           "Returning primary keys of prefetched 'filter' rels as part of get_columns() is deprecated and will "
741         . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
742         ) if (
743           ! $ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}
744             and
745           defined $self->{related_resultsets}{$col}
746             and
747           defined $self->{related_resultsets}{$col}->get_cache
748         );
749
750         $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}));
751       }
752     }
753   }
754   return %{$self->{_column_data}};
755 }
756
757 =head2 get_dirty_columns
758
759   my %data = $result->get_dirty_columns;
760
761 =over
762
763 =item Arguments: none
764
765 =item Return Value: A hash of column, value pairs
766
767 =back
768
769 Only returns the column, value pairs for those columns that have been
770 changed on this object since the last L</update> or L</insert> call.
771
772 See L</get_columns> to fetch all column/value pairs.
773
774 =cut
775
776 sub get_dirty_columns {
777   my $self = shift;
778   return map { $_ => $self->{_column_data}{$_} }
779            keys %{$self->{_dirty_columns}};
780 }
781
782 =head2 make_column_dirty
783
784   $result->make_column_dirty($col)
785
786 =over
787
788 =item Arguments: $columnname
789
790 =item Return Value: not defined
791
792 =back
793
794 Throws an exception if the column does not exist.
795
796 Marks a column as having been changed regardless of whether it has
797 really changed.
798
799 =cut
800
801 sub make_column_dirty {
802   my ($self, $column) = @_;
803
804   $self->throw_exception( "No such column '${column}' on " . ref $self )
805     unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
806
807   # the entire clean/dirty code relies on exists, not on true/false
808   return 1 if exists $self->{_dirty_columns}{$column};
809
810   $self->{_dirty_columns}{$column} = 1;
811
812   # if we are just now making the column dirty, and if there is an inflated
813   # value, force it over the deflated one
814   if (exists $self->{_inflated_column}{$column}) {
815     $self->store_column($column,
816       $self->_deflated_column(
817         $column, $self->{_inflated_column}{$column}
818       )
819     );
820   }
821 }
822
823 =head2 get_inflated_columns
824
825   my %inflated_data = $obj->get_inflated_columns;
826
827 =over
828
829 =item Arguments: none
830
831 =item Return Value: A hash of column, object|value pairs
832
833 =back
834
835 Returns a hash of all column keys and associated values. Values for any
836 columns set to use inflation will be inflated and returns as objects.
837
838 See L</get_columns> to get the uninflated values.
839
840 See L<DBIx::Class::InflateColumn> for how to setup inflation.
841
842 =cut
843
844 sub get_inflated_columns {
845   my $self = shift;
846
847   my $loaded_colinfo = $self->result_source->columns_info;
848   $self->has_column_loaded($_) or delete $loaded_colinfo->{$_}
849     for keys %$loaded_colinfo;
850
851   my %cols_to_return = ( %{$self->{_column_data}}, %$loaded_colinfo );
852
853   unless ($ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}) {
854     for (keys %$loaded_colinfo) {
855       # if cached related_resultset is present assume this was a prefetch
856       if (
857         $loaded_colinfo->{$_}{_inflate_info}
858           and
859         defined $self->{related_resultsets}{$_}
860           and
861         defined $self->{related_resultsets}{$_}->get_cache
862       ) {
863         carp_unique(
864           "Returning prefetched 'filter' rels as part of get_inflated_columns() is deprecated and will "
865         . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
866         );
867         last;
868       }
869     }
870   }
871
872   map { $_ => (
873   (
874     ! exists $loaded_colinfo->{$_}
875       or
876     (
877       exists $loaded_colinfo->{$_}{accessor}
878         and
879       ! defined $loaded_colinfo->{$_}{accessor}
880     )
881   ) ? $self->get_column($_)
882     : $self->${ \(
883       defined $loaded_colinfo->{$_}{accessor}
884         ? $loaded_colinfo->{$_}{accessor}
885         : $_
886       )}
887   )} keys %cols_to_return;
888 }
889
890 sub _is_column_numeric {
891     my ($self, $column) = @_;
892
893     my $rsrc;
894
895     return undef
896       unless ( $rsrc = $self->result_source )->has_column($column);
897
898     my $colinfo = $rsrc->column_info ($column);
899
900     # cache for speed (the object may *not* have a resultsource instance)
901     if (
902       ! defined $colinfo->{is_numeric}
903         and
904       my $storage = dbic_internal_try { $rsrc->schema->storage }
905     ) {
906       $colinfo->{is_numeric} =
907         $storage->is_datatype_numeric ($colinfo->{data_type})
908           ? 1
909           : 0
910         ;
911     }
912
913     return $colinfo->{is_numeric};
914 }
915
916 =head2 set_column
917
918   $result->set_column($col => $val);
919
920 =over
921
922 =item Arguments: $columnname, $value
923
924 =item Return Value: $value
925
926 =back
927
928 Sets a raw column value. If the new value is different from the old one,
929 the column is marked as dirty for when you next call L</update>.
930
931 If passed an object or reference as a value, this method will happily
932 attempt to store it, and a later L</insert> or L</update> will try and
933 stringify/numify as appropriate. To set an object to be deflated
934 instead, see L</set_inflated_columns>, or better yet, use L</$column_accessor>.
935
936 =cut
937
938 sub set_column {
939   my ($self, $column, $new_value) = @_;
940
941   my $had_value = $self->has_column_loaded($column);
942   my $old_value = $self->get_column($column);
943
944   $new_value = $self->store_column($column, $new_value);
945
946   my $dirty =
947     $self->{_dirty_columns}{$column}
948       ||
949     ( $self->in_storage # no point tracking dirtyness on uninserted data
950       ? ! $self->_eq_column_values ($column, $old_value, $new_value)
951       : 1
952     )
953   ;
954
955   if ($dirty) {
956     # FIXME sadly the update code just checks for keys, not for their value
957     $self->{_dirty_columns}{$column} = 1;
958
959     # Clear out the relation/inflation cache related to this column
960     #
961     # FIXME - this is a quick *largely incorrect* hack, pending a more
962     # serious rework during the merge of single and filter rels
963     my $rel_names = $self->result_source->{_relationships};
964     for my $rel_name (keys %$rel_names) {
965
966       my $acc = $rel_names->{$rel_name}{attrs}{accessor} || '';
967
968       if ( $acc eq 'single' and $rel_names->{$rel_name}{attrs}{fk_columns}{$column} ) {
969         delete $self->{related_resultsets}{$rel_name};
970         delete $self->{_relationship_data}{$rel_name};
971         #delete $self->{_inflated_column}{$rel_name};
972       }
973       elsif ( $acc eq 'filter' and $rel_name eq $column) {
974         delete $self->{related_resultsets}{$rel_name};
975         #delete $self->{_relationship_data}{$rel_name};
976         delete $self->{_inflated_column}{$rel_name};
977       }
978     }
979
980     if (
981       # value change from something (even if NULL)
982       $had_value
983         and
984       # no storage - no storage-value
985       $self->in_storage
986         and
987       # no value already stored (multiple changes before commit to storage)
988       ! exists $self->{_column_data_in_storage}{$column}
989         and
990       $self->_track_storage_value($column)
991     ) {
992       $self->{_column_data_in_storage}{$column} = $old_value;
993     }
994   }
995
996   return $new_value;
997 }
998
999 sub _eq_column_values {
1000   my ($self, $col, $old, $new) = @_;
1001
1002   if (defined $old xor defined $new) {
1003     return 0;
1004   }
1005   elsif (not defined $old) {  # both undef
1006     return 1;
1007   }
1008   elsif (
1009     is_literal_value $old
1010       or
1011     is_literal_value $new
1012   ) {
1013     return 0;
1014   }
1015   elsif ($old eq $new) {
1016     return 1;
1017   }
1018   elsif ($self->_is_column_numeric($col)) {  # do a numeric comparison if datatype allows it
1019     return $old == $new;
1020   }
1021   else {
1022     return 0;
1023   }
1024 }
1025
1026 # returns a boolean indicating if the passed column should have its original
1027 # value tracked between column changes and commitment to storage
1028 sub _track_storage_value {
1029   my ($self, $col) = @_;
1030   return scalar grep
1031     { $col eq $_ }
1032     $self->result_source->primary_columns
1033   ;
1034 }
1035
1036 =head2 set_columns
1037
1038   $result->set_columns({ $col => $val, ... });
1039
1040 =over
1041
1042 =item Arguments: \%columndata
1043
1044 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1045
1046 =back
1047
1048 Sets multiple column, raw value pairs at once.
1049
1050 Works as L</set_column>.
1051
1052 =cut
1053
1054 sub set_columns {
1055   my ($self, $values) = @_;
1056   $self->set_column( $_, $values->{$_} ) for keys %$values;
1057   return $self;
1058 }
1059
1060 =head2 set_inflated_columns
1061
1062   $result->set_inflated_columns({ $col => $val, $rel_name => $obj, ... });
1063
1064 =over
1065
1066 =item Arguments: \%columndata
1067
1068 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1069
1070 =back
1071
1072 Sets more than one column value at once. Any inflated values are
1073 deflated and the raw values stored.
1074
1075 Any related values passed as Result objects, using the relation name as a
1076 key, are reduced to the appropriate foreign key values and stored. If
1077 instead of related result objects, a hashref of column, value data is
1078 passed, will create the related object first then store.
1079
1080 Will even accept arrayrefs of data as a value to a
1081 L<DBIx::Class::Relationship/has_many> key, and create the related
1082 objects if necessary.
1083
1084 Be aware that the input hashref might be edited in place, so don't rely
1085 on it being the same after a call to C<set_inflated_columns>. If you
1086 need to preserve the hashref, it is sufficient to pass a shallow copy
1087 to C<set_inflated_columns>, e.g. ( { %{ $href } } )
1088
1089 See also L<DBIx::Class::Relationship::Base/set_from_related>.
1090
1091 =cut
1092
1093 sub set_inflated_columns {
1094   my ( $self, $upd ) = @_;
1095   my $rsrc;
1096   foreach my $key (keys %$upd) {
1097     if (ref $upd->{$key}) {
1098       $rsrc ||= $self->result_source;
1099       my $info = $rsrc->relationship_info($key);
1100       my $acc_type = $info->{attrs}{accessor} || '';
1101
1102       if ($acc_type eq 'single') {
1103         my $rel_obj = delete $upd->{$key};
1104         $self->set_from_related($key => $rel_obj);
1105         $self->{_relationship_data}{$key} = $rel_obj;
1106       }
1107       elsif ($acc_type eq 'multi') {
1108         $self->throw_exception(
1109           "Recursive update is not supported over relationships of type '$acc_type' ($key)"
1110         );
1111       }
1112       elsif (
1113         $rsrc->has_column($key)
1114           and
1115         exists $rsrc->column_info($key)->{_inflate_info}
1116       ) {
1117         $self->set_inflated_column($key, delete $upd->{$key});
1118       }
1119     }
1120   }
1121   $self->set_columns($upd);
1122 }
1123
1124 =head2 copy
1125
1126   my $copy = $orig->copy({ change => $to, ... });
1127
1128 =over
1129
1130 =item Arguments: \%replacementdata
1131
1132 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass> copy
1133
1134 =back
1135
1136 Inserts a new row into the database, as a copy of the original
1137 object. If a hashref of replacement data is supplied, these will take
1138 precedence over data in the original. Also any columns which have
1139 the L<column info attribute|DBIx::Class::ResultSource/add_columns>
1140 C<< is_auto_increment => 1 >> are explicitly removed before the copy,
1141 so that the database can insert its own autoincremented values into
1142 the new object.
1143
1144 Relationships will be followed by the copy procedure B<only> if the
1145 relationship specifies a true value for its
1146 L<cascade_copy|DBIx::Class::Relationship::Base> attribute. C<cascade_copy>
1147 is set by default on C<has_many> relationships and unset on all others.
1148
1149 =cut
1150
1151 sub copy {
1152   my ($self, $changes) = @_;
1153   $changes ||= {};
1154   my $col_data = { $self->get_columns };
1155
1156   my $rsrc = $self->result_source;
1157
1158   my $colinfo = $rsrc->columns_info;
1159   foreach my $col (keys %$col_data) {
1160     delete $col_data->{$col}
1161       if ( ! $colinfo->{$col} or $colinfo->{$col}{is_auto_increment} );
1162   }
1163
1164   my $new = { _column_data => $col_data };
1165   bless $new, ref $self;
1166
1167   $new->result_source($rsrc);
1168   $new->set_inflated_columns($changes);
1169   $new->insert;
1170
1171   # Its possible we'll have 2 relations to the same Source. We need to make
1172   # sure we don't try to insert the same row twice else we'll violate unique
1173   # constraints
1174   my $rel_names_copied = {};
1175
1176   foreach my $rel_name ($rsrc->relationships) {
1177     my $rel_info = $rsrc->relationship_info($rel_name);
1178
1179     next unless $rel_info->{attrs}{cascade_copy};
1180
1181     my $foreign_vals;
1182     my $copied = $rel_names_copied->{ $rel_info->{source} } ||= {};
1183
1184     $copied->{$_->ID}++ or $_->copy(
1185
1186       $foreign_vals ||= $rsrc->_resolve_relationship_condition(
1187         infer_values_based_on => {},
1188         rel_name => $rel_name,
1189         self_result_object => $new,
1190
1191         self_alias => "\xFE", # irrelevant
1192         foreign_alias => "\xFF", # irrelevant,
1193       )->{inferred_values}
1194
1195     ) for $self->related_resultset($rel_name)->all;
1196   }
1197   return $new;
1198 }
1199
1200 =head2 store_column
1201
1202   $result->store_column($col => $val);
1203
1204 =over
1205
1206 =item Arguments: $columnname, $value
1207
1208 =item Return Value: The value sent to storage
1209
1210 =back
1211
1212 Set a raw value for a column without marking it as changed. This
1213 method is used internally by L</set_column> which you should probably
1214 be using.
1215
1216 This is the lowest level at which data is set on a result object,
1217 extend this method to catch all data setting methods.
1218
1219 =cut
1220
1221 sub store_column {
1222   my ($self, $column, $value) = @_;
1223   $self->throw_exception( "No such column '${column}' on " . ref $self )
1224     unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
1225   $self->throw_exception( "set_column called for ${column} without value" )
1226     if @_ < 3;
1227
1228   return $self->{_column_data}{$column} = $value
1229     unless length ref $value and my $vref = is_plain_value( $value );
1230
1231   # if we are dealing with a value/ref - there are a couple possibilities
1232   # unpack the underlying piece of data and stringify all objects explicitly
1233   # ( to accomodate { -value => ... } and guard against overloaded objects
1234   # with defined stringification AND fallback => 0 (ugh!)
1235   $self->{_column_data}{$column} = defined blessed $$vref
1236     ? "$$vref"
1237     : $$vref
1238   ;
1239 }
1240
1241 =head2 inflate_result
1242
1243   Class->inflate_result($result_source, \%me, \%prefetch?)
1244
1245 =over
1246
1247 =item Arguments: L<$result_source|DBIx::Class::ResultSource>, \%columndata, \%prefetcheddata
1248
1249 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1250
1251 =back
1252
1253 All L<DBIx::Class::ResultSet> methods that retrieve data from the
1254 database and turn it into result objects call this method.
1255
1256 Extend this method in your Result classes to hook into this process,
1257 for example to rebless the result into a different class.
1258
1259 Reblessing can also be done more easily by setting C<result_class> in
1260 your Result class. See L<DBIx::Class::ResultSource/result_class>.
1261
1262 Different types of results can also be created from a particular
1263 L<DBIx::Class::ResultSet>, see L<DBIx::Class::ResultSet/result_class>.
1264
1265 =cut
1266
1267 sub inflate_result {
1268   my ($class, $rsrc, $me, $prefetch) = @_;
1269
1270   my $new = bless
1271     { _column_data => $me, _result_source => $rsrc },
1272     ref $class || $class
1273   ;
1274
1275   if ($prefetch) {
1276     for my $rel_name ( keys %$prefetch ) {
1277
1278       my $relinfo = $rsrc->relationship_info($rel_name) or do {
1279         my $err = sprintf
1280           "Inflation into non-existent relationship '%s' of '%s' requested",
1281           $rel_name,
1282           $rsrc->source_name,
1283         ;
1284         if (my ($colname) = sort { length($a) <=> length ($b) } keys %{$prefetch->{$rel_name}[0] || {}} ) {
1285           $err .= sprintf ", check the inflation specification (columns/as) ending in '...%s.%s'",
1286           $rel_name,
1287           $colname,
1288         }
1289
1290         $rsrc->throw_exception($err);
1291       };
1292
1293       $class->throw_exception("No accessor type declared for prefetched relationship '$rel_name'")
1294         unless $relinfo->{attrs}{accessor};
1295
1296       my $rel_rs = $new->related_resultset($rel_name);
1297
1298       my @rel_objects;
1299       if (
1300         @{ $prefetch->{$rel_name} || [] }
1301           and
1302         ref($prefetch->{$rel_name}) ne $DBIx::Class::ResultSource::RowParser::Util::null_branch_class
1303       ) {
1304
1305         if (ref $prefetch->{$rel_name}[0] eq 'ARRAY') {
1306           my $rel_rsrc = $rel_rs->result_source;
1307           my $rel_class = $rel_rs->result_class;
1308           my $rel_inflator = $rel_class->can('inflate_result');
1309           @rel_objects = map
1310             { $rel_class->$rel_inflator ( $rel_rsrc, @$_ ) }
1311             @{$prefetch->{$rel_name}}
1312           ;
1313         }
1314         else {
1315           @rel_objects = $rel_rs->result_class->inflate_result(
1316             $rel_rs->result_source, @{$prefetch->{$rel_name}}
1317           );
1318         }
1319       }
1320
1321       if ($relinfo->{attrs}{accessor} eq 'single') {
1322         $new->{_relationship_data}{$rel_name} = $rel_objects[0];
1323       }
1324       elsif ($relinfo->{attrs}{accessor} eq 'filter') {
1325         $new->{_inflated_column}{$rel_name} = $rel_objects[0];
1326       }
1327
1328       $rel_rs->set_cache(\@rel_objects);
1329     }
1330   }
1331
1332   $new->in_storage (1);
1333   return $new;
1334 }
1335
1336 =head2 update_or_insert
1337
1338   $result->update_or_insert
1339
1340 =over
1341
1342 =item Arguments: none
1343
1344 =item Return Value: Result of update or insert operation
1345
1346 =back
1347
1348 L</update>s the object if it's already in the database, according to
1349 L</in_storage>, else L</insert>s it.
1350
1351 =head2 insert_or_update
1352
1353   $obj->insert_or_update
1354
1355 Alias for L</update_or_insert>
1356
1357 =cut
1358
1359 sub insert_or_update {
1360   DBIx::Class::_ENV_::ASSERT_NO_INTERNAL_INDIRECT_CALLS and fail_on_internal_call;
1361   shift->update_or_insert(@_);
1362 }
1363
1364 sub update_or_insert {
1365   my $self = shift;
1366   return ($self->in_storage ? $self->update : $self->insert);
1367 }
1368
1369 =head2 is_changed
1370
1371   my @changed_col_names = $result->is_changed();
1372   if ($result->is_changed()) { ... }
1373
1374 =over
1375
1376 =item Arguments: none
1377
1378 =item Return Value: 0|1 or @columnnames
1379
1380 =back
1381
1382 In list context returns a list of columns with uncommited changes, or
1383 in scalar context returns a true value if there are uncommitted
1384 changes.
1385
1386 =cut
1387
1388 sub is_changed {
1389   return keys %{shift->{_dirty_columns} || {}};
1390 }
1391
1392 =head2 is_column_changed
1393
1394   if ($result->is_column_changed('col')) { ... }
1395
1396 =over
1397
1398 =item Arguments: $columname
1399
1400 =item Return Value: 0|1
1401
1402 =back
1403
1404 Returns a true value if the column has uncommitted changes.
1405
1406 =cut
1407
1408 sub is_column_changed {
1409   my( $self, $col ) = @_;
1410   return exists $self->{_dirty_columns}->{$col};
1411 }
1412
1413 =head2 result_source
1414
1415   my $resultsource = $result->result_source;
1416
1417 =over
1418
1419 =item Arguments: L<$result_source?|DBIx::Class::ResultSource>
1420
1421 =item Return Value: L<$result_source|DBIx::Class::ResultSource>
1422
1423 =back
1424
1425 Accessor to the L<DBIx::Class::ResultSource> this object was created from.
1426
1427 =cut
1428
1429 sub result_source {
1430   $_[0]->throw_exception( 'result_source can be called on instances only' )
1431     unless ref $_[0];
1432
1433   @_ > 1
1434     ? $_[0]->{_result_source} = $_[1]
1435
1436     # note this is a || not a ||=, the difference is important
1437     : $_[0]->{_result_source} || do {
1438         $_[0]->can('result_source_instance')
1439           ? $_[0]->result_source_instance
1440           : $_[0]->throw_exception(
1441             "No result source instance registered for @{[ ref $_[0] ]}, did you forget to call @{[ ref $_[0] ]}->table(...) ?"
1442           )
1443       }
1444   ;
1445 }
1446
1447 =head2 register_column
1448
1449   $column_info = { .... };
1450   $class->register_column($column_name, $column_info);
1451
1452 =over
1453
1454 =item Arguments: $columnname, \%columninfo
1455
1456 =item Return Value: not defined
1457
1458 =back
1459
1460 Registers a column on the class. If the column_info has an 'accessor'
1461 key, creates an accessor named after the value if defined; if there is
1462 no such key, creates an accessor with the same name as the column
1463
1464 The column_info attributes are described in
1465 L<DBIx::Class::ResultSource/add_columns>
1466
1467 =cut
1468
1469 sub register_column {
1470   my ($class, $col, $info) = @_;
1471   my $acc = $col;
1472   if (exists $info->{accessor}) {
1473     return unless defined $info->{accessor};
1474     $acc = [ $info->{accessor}, $col ];
1475   }
1476   $class->mk_group_accessors('column' => $acc);
1477 }
1478
1479 =head2 get_from_storage
1480
1481   my $copy = $result->get_from_storage($attrs)
1482
1483 =over
1484
1485 =item Arguments: \%attrs
1486
1487 =item Return Value: A Result object
1488
1489 =back
1490
1491 Fetches a fresh copy of the Result object from the database and returns it.
1492 Throws an exception if a proper WHERE clause identifying the database row
1493 can not be constructed (i.e. if the original object does not contain its
1494 entire
1495  L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
1496 ). If passed the \%attrs argument, will first apply these attributes to
1497 the resultset used to find the row.
1498
1499 This copy can then be used to compare to an existing result object, to
1500 determine if any changes have been made in the database since it was
1501 created.
1502
1503 To just update your Result object with any latest changes from the
1504 database, use L</discard_changes> instead.
1505
1506 The \%attrs argument should be compatible with
1507 L<DBIx::Class::ResultSet/ATTRIBUTES>.
1508
1509 =cut
1510
1511 sub get_from_storage {
1512     my $self = shift @_;
1513     my $attrs = shift @_;
1514     my $resultset = $self->result_source->resultset;
1515
1516     if(defined $attrs) {
1517       $resultset = $resultset->search(undef, $attrs);
1518     }
1519
1520     return $resultset->find($self->_storage_ident_condition);
1521 }
1522
1523 =head2 discard_changes
1524
1525   $result->discard_changes
1526
1527 =over
1528
1529 =item Arguments: none or $attrs
1530
1531 =item Return Value: self (updates object in-place)
1532
1533 =back
1534
1535 Re-selects the row from the database, losing any changes that had
1536 been made. Throws an exception if a proper C<WHERE> clause identifying
1537 the database row can not be constructed (i.e. if the original object
1538 does not contain its entire
1539 L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>).
1540
1541 This method can also be used to refresh from storage, retrieving any
1542 changes made since the row was last read from storage.
1543
1544 $attrs, if supplied, is expected to be a hashref of attributes suitable for passing as the
1545 second argument to C<< $resultset->search($cond, $attrs) >>;
1546
1547 Note: If you are using L<DBIx::Class::Storage::DBI::Replicated> as your
1548 storage, a default of
1549 L<< C<< { force_pool => 'master' } >>
1550 |DBIx::Class::Storage::DBI::Replicated/SYNOPSIS >>  is automatically set for
1551 you. Prior to C<< DBIx::Class 0.08109 >> (before 2010) one would have been
1552 required to explicitly wrap the entire operation in a transaction to guarantee
1553 that up-to-date results are read from the master database.
1554
1555 =cut
1556
1557 sub discard_changes {
1558   my ($self, $attrs) = @_;
1559   return unless $self->in_storage; # Don't reload if we aren't real!
1560
1561   # add a replication default to read from the master only
1562   $attrs = { force_pool => 'master', %{$attrs||{}} };
1563
1564   if( my $current_storage = $self->get_from_storage($attrs)) {
1565
1566     # Set $self to the current.
1567     %$self = %$current_storage;
1568
1569     # Avoid a possible infinite loop with
1570     # sub DESTROY { $_[0]->discard_changes }
1571     bless $current_storage, 'Do::Not::Exist';
1572
1573     return $self;
1574   }
1575   else {
1576     $self->in_storage(0);
1577     return $self;
1578   }
1579 }
1580
1581 =head2 throw_exception
1582
1583 See L<DBIx::Class::Schema/throw_exception>.
1584
1585 =cut
1586
1587 sub throw_exception {
1588   my $self=shift;
1589
1590   if (
1591     ! DBIx::Class::_Util::in_internal_try
1592       and
1593     my $rsrc = dbic_internal_try { $self->result_source }
1594   ) {
1595     $rsrc->throw_exception(@_)
1596   }
1597   else {
1598     DBIx::Class::Exception->throw(@_);
1599   }
1600 }
1601
1602 =head2 id
1603
1604   my @pk = $result->id;
1605
1606 =over
1607
1608 =item Arguments: none
1609
1610 =item Returns: A list of primary key values
1611
1612 =back
1613
1614 Returns the primary key(s) for a row. Can't be called as a class method.
1615 Actually implemented in L<DBIx::Class::PK>
1616
1617 =head1 FURTHER QUESTIONS?
1618
1619 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1620
1621 =head1 COPYRIGHT AND LICENSE
1622
1623 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1624 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1625 redistribute it and/or modify it under the same terms as the
1626 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
1627
1628 =cut
1629
1630 1;