c8b57b696c61c9764343541852239f487d13b5b4
[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 'dbic_internal_try';
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->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 = $self->result_source
376                                            ->related_source($rel_name)
377                                            ->resultset
378                                            ->find($them)
379       ) {
380         %{$rel_obj} = %{$existing};
381       }
382       else {
383         $rel_obj->insert;
384       }
385
386       $self->{_rel_in_storage}{$rel_name} = 1;
387     }
388
389     $self->set_from_related($rel_name, $rel_obj);
390     delete $related_stuff{$rel_name};
391   }
392
393   # start a transaction here if not started yet and there is more stuff
394   # to insert after us
395   if (keys %related_stuff) {
396     $rollback_guard ||= $storage->txn_scope_guard
397   }
398
399   MULTICREATE_DEBUG and do {
400     no warnings 'uninitialized';
401     print STDERR "MC $self inserting (".join(', ', $self->get_columns).")\n";
402   };
403
404   # perform the insert - the storage will return everything it is asked to
405   # (autoinc primary columns and any retrieve_on_insert columns)
406   my %current_rowdata = $self->get_columns;
407   my $returned_cols = $storage->insert(
408     $rsrc,
409     { %current_rowdata }, # what to insert, copy because the storage *will* change it
410   );
411
412   for (keys %$returned_cols) {
413     $self->store_column($_, $returned_cols->{$_})
414       # this ensures we fire store_column only once
415       # (some asshats like overriding it)
416       if (
417         (!exists $current_rowdata{$_})
418           or
419         (defined $current_rowdata{$_} xor defined $returned_cols->{$_})
420           or
421         (defined $current_rowdata{$_} and $current_rowdata{$_} ne $returned_cols->{$_})
422       );
423   }
424
425   delete $self->{_column_data_in_storage};
426   $self->in_storage(1);
427
428   $self->{_dirty_columns} = {};
429   $self->{related_resultsets} = {};
430
431   foreach my $rel_name (keys %related_stuff) {
432     next unless $rsrc->has_relationship ($rel_name);
433
434     my @cands = ref $related_stuff{$rel_name} eq 'ARRAY'
435       ? @{$related_stuff{$rel_name}}
436       : $related_stuff{$rel_name}
437     ;
438
439     if (@cands && blessed $cands[0] && $cands[0]->isa('DBIx::Class::Row')
440     ) {
441       my $reverse = $rsrc->reverse_relationship_info($rel_name);
442       foreach my $obj (@cands) {
443         $obj->set_from_related($_, $self) for keys %$reverse;
444         if ($self->__their_pk_needs_us($rel_name)) {
445           if (exists $self->{_ignore_at_insert}{$rel_name}) {
446             MULTICREATE_DEBUG and print STDERR "MC $self skipping post-insert on $rel_name\n";
447           }
448           else {
449             MULTICREATE_DEBUG and print STDERR "MC $self inserting $rel_name $obj\n";
450             $obj->insert;
451           }
452         } else {
453           MULTICREATE_DEBUG and print STDERR "MC $self post-inserting $obj\n";
454           $obj->insert();
455         }
456       }
457     }
458   }
459
460   delete $self->{_ignore_at_insert};
461
462   $rollback_guard->commit if $rollback_guard;
463
464   return $self;
465 }
466
467 =head2 in_storage
468
469   $result->in_storage; # Get value
470   $result->in_storage(1); # Set value
471
472 =over
473
474 =item Arguments: none or 1|0
475
476 =item Return Value: 1|0
477
478 =back
479
480 Indicates whether the object exists as a row in the database or
481 not. This is set to true when L<DBIx::Class::ResultSet/find>,
482 L<DBIx::Class::ResultSet/create> or L<DBIx::Class::Row/insert>
483 are invoked.
484
485 Creating a result object using L<DBIx::Class::ResultSet/new_result>, or
486 calling L</delete> on one, sets it to false.
487
488
489 =head2 update
490
491   $result->update(\%columns?)
492
493 =over
494
495 =item Arguments: none or a hashref
496
497 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
498
499 =back
500
501 Throws an exception if the result object is not yet in the database,
502 according to L</in_storage>. Returns the object itself.
503
504 This method issues an SQL UPDATE query to commit any changes to the
505 object to the database if required (see L</get_dirty_columns>).
506 It throws an exception if a proper WHERE clause uniquely identifying
507 the database row can not be constructed (see
508 L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
509 for more details).
510
511 Also takes an optional hashref of C<< column_name => value >> pairs
512 to update on the object first. Be aware that the hashref will be
513 passed to C<set_inflated_columns>, which might edit it in place, so
514 don't rely on it being the same after a call to C<update>.  If you
515 need to preserve the hashref, it is sufficient to pass a shallow copy
516 to C<update>, e.g. ( { %{ $href } } )
517
518 If the values passed or any of the column values set on the object
519 contain scalar references, e.g.:
520
521   $result->last_modified(\'NOW()')->update();
522   # OR
523   $result->update({ last_modified => \'NOW()' });
524
525 The update will pass the values verbatim into SQL. (See
526 L<SQL::Abstract> docs).  The values in your Result object will NOT change
527 as a result of the update call, if you want the object to be updated
528 with the actual values from the database, call L</discard_changes>
529 after the update.
530
531   $result->update()->discard_changes();
532
533 To determine before calling this method, which column values have
534 changed and will be updated, call L</get_dirty_columns>.
535
536 To check if any columns will be updated, call L</is_changed>.
537
538 To force a column to be updated, call L</make_column_dirty> before
539 this method.
540
541 =cut
542
543 sub update {
544   my ($self, $upd) = @_;
545
546   $self->set_inflated_columns($upd) if $upd;
547
548   my %to_update = $self->get_dirty_columns
549     or return $self;
550
551   $self->throw_exception( "Not in database" ) unless $self->in_storage;
552
553   my $rows = $self->result_source->storage->update(
554     $self->result_source, \%to_update, $self->_storage_ident_condition
555   );
556   if ($rows == 0) {
557     $self->throw_exception( "Can't update ${self}: row not found" );
558   } elsif ($rows > 1) {
559     $self->throw_exception("Can't update ${self}: updated more than one row");
560   }
561   $self->{_dirty_columns} = {};
562   $self->{related_resultsets} = {};
563   delete $self->{_column_data_in_storage};
564   return $self;
565 }
566
567 =head2 delete
568
569   $result->delete
570
571 =over
572
573 =item Arguments: none
574
575 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
576
577 =back
578
579 Throws an exception if the object is not in the database according to
580 L</in_storage>. Also throws an exception if a proper WHERE clause
581 uniquely identifying the database row can not be constructed (see
582 L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
583 for more details).
584
585 The object is still perfectly usable, but L</in_storage> will
586 now return 0 and the object must be reinserted using L</insert>
587 before it can be used to L</update> the row again.
588
589 If you delete an object in a class with a C<has_many> relationship, an
590 attempt is made to delete all the related objects as well. To turn
591 this behaviour off, pass C<< cascade_delete => 0 >> in the C<$attr>
592 hashref of the relationship, see L<DBIx::Class::Relationship>. Any
593 database-level cascade or restrict will take precedence over a
594 DBIx-Class-based cascading delete, since DBIx-Class B<deletes the
595 main row first> and only then attempts to delete any remaining related
596 rows.
597
598 If you delete an object within a txn_do() (see L<DBIx::Class::Storage/txn_do>)
599 and the transaction subsequently fails, the result object will remain marked as
600 not being in storage. If you know for a fact that the object is still in
601 storage (i.e. by inspecting the cause of the transaction's failure), you can
602 use C<< $obj->in_storage(1) >> to restore consistency between the object and
603 the database. This would allow a subsequent C<< $obj->delete >> to work
604 as expected.
605
606 See also L<DBIx::Class::ResultSet/delete>.
607
608 =cut
609
610 sub delete {
611   my $self = shift;
612   if (ref $self) {
613     $self->throw_exception( "Not in database" ) unless $self->in_storage;
614
615     $self->result_source->storage->delete(
616       $self->result_source, $self->_storage_ident_condition
617     );
618
619     delete $self->{_column_data_in_storage};
620     $self->in_storage(0);
621   }
622   else {
623     my $rsrc = dbic_internal_try { $self->result_source_instance }
624       or $self->throw_exception("Can't do class delete without a ResultSource instance");
625
626     my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? { %{pop(@_)} } : {};
627     my $query = ref $_[0] eq 'HASH' ? $_[0] : {@_};
628     $rsrc->resultset->search(@_)->delete;
629   }
630   return $self;
631 }
632
633 =head2 get_column
634
635   my $val = $result->get_column($col);
636
637 =over
638
639 =item Arguments: $columnname
640
641 =item Return Value: The value of the column
642
643 =back
644
645 Throws an exception if the column name given doesn't exist according
646 to L<has_column|DBIx::Class::ResultSource/has_column>.
647
648 Returns a raw column value from the result object, if it has already
649 been fetched from the database or set by an accessor.
650
651 If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
652 will be deflated and returned.
653
654 Note that if you used the C<columns> or the C<select/as>
655 L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
656 which C<$result> was derived, and B<did not include> C<$columnname> in the list,
657 this method will return C<undef> even if the database contains some value.
658
659 To retrieve all loaded column values as a hash, use L</get_columns>.
660
661 =cut
662
663 sub get_column {
664   my ($self, $column) = @_;
665   $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
666
667   return $self->{_column_data}{$column}
668     if exists $self->{_column_data}{$column};
669
670   if (exists $self->{_inflated_column}{$column}) {
671     # deflate+return cycle
672     return $self->store_column($column, $self->_deflated_column(
673       $column, $self->{_inflated_column}{$column}
674     ));
675   }
676
677   $self->throw_exception( "No such column '${column}' on " . ref $self )
678     unless $self->result_source->has_column($column);
679
680   return undef;
681 }
682
683 =head2 has_column_loaded
684
685   if ( $result->has_column_loaded($col) ) {
686      print "$col has been loaded from db";
687   }
688
689 =over
690
691 =item Arguments: $columnname
692
693 =item Return Value: 0|1
694
695 =back
696
697 Returns a true value if the column value has been loaded from the
698 database (or set locally).
699
700 =cut
701
702 sub has_column_loaded {
703   my ($self, $column) = @_;
704   $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
705
706   return (
707     exists $self->{_inflated_column}{$column}
708       or
709     exists $self->{_column_data}{$column}
710   ) ? 1 : 0;
711 }
712
713 =head2 get_columns
714
715   my %data = $result->get_columns;
716
717 =over
718
719 =item Arguments: none
720
721 =item Return Value: A hash of columnname, value pairs.
722
723 =back
724
725 Returns all loaded column data as a hash, containing raw values. To
726 get just one value for a particular column, use L</get_column>.
727
728 See L</get_inflated_columns> to get the inflated values.
729
730 =cut
731
732 sub get_columns {
733   my $self = shift;
734   if (exists $self->{_inflated_column}) {
735     # deflate cycle for each inflation, including filter rels
736     foreach my $col (keys %{$self->{_inflated_column}}) {
737       unless (exists $self->{_column_data}{$col}) {
738
739         # if cached related_resultset is present assume this was a prefetch
740         carp_unique(
741           "Returning primary keys of prefetched 'filter' rels as part of get_columns() is deprecated and will "
742         . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
743         ) if (
744           ! $ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}
745             and
746           defined $self->{related_resultsets}{$col}
747             and
748           defined $self->{related_resultsets}{$col}->get_cache
749         );
750
751         $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}));
752       }
753     }
754   }
755   return %{$self->{_column_data}};
756 }
757
758 =head2 get_dirty_columns
759
760   my %data = $result->get_dirty_columns;
761
762 =over
763
764 =item Arguments: none
765
766 =item Return Value: A hash of column, value pairs
767
768 =back
769
770 Only returns the column, value pairs for those columns that have been
771 changed on this object since the last L</update> or L</insert> call.
772
773 See L</get_columns> to fetch all column/value pairs.
774
775 =cut
776
777 sub get_dirty_columns {
778   my $self = shift;
779   return map { $_ => $self->{_column_data}{$_} }
780            keys %{$self->{_dirty_columns}};
781 }
782
783 =head2 make_column_dirty
784
785   $result->make_column_dirty($col)
786
787 =over
788
789 =item Arguments: $columnname
790
791 =item Return Value: not defined
792
793 =back
794
795 Throws an exception if the column does not exist.
796
797 Marks a column as having been changed regardless of whether it has
798 really changed.
799
800 =cut
801
802 sub make_column_dirty {
803   my ($self, $column) = @_;
804
805   $self->throw_exception( "No such column '${column}' on " . ref $self )
806     unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
807
808   # the entire clean/dirty code relies on exists, not on true/false
809   return 1 if exists $self->{_dirty_columns}{$column};
810
811   $self->{_dirty_columns}{$column} = 1;
812
813   # if we are just now making the column dirty, and if there is an inflated
814   # value, force it over the deflated one
815   if (exists $self->{_inflated_column}{$column}) {
816     $self->store_column($column,
817       $self->_deflated_column(
818         $column, $self->{_inflated_column}{$column}
819       )
820     );
821   }
822 }
823
824 =head2 get_inflated_columns
825
826   my %inflated_data = $obj->get_inflated_columns;
827
828 =over
829
830 =item Arguments: none
831
832 =item Return Value: A hash of column, object|value pairs
833
834 =back
835
836 Returns a hash of all column keys and associated values. Values for any
837 columns set to use inflation will be inflated and returns as objects.
838
839 See L</get_columns> to get the uninflated values.
840
841 See L<DBIx::Class::InflateColumn> for how to setup inflation.
842
843 =cut
844
845 sub get_inflated_columns {
846   my $self = shift;
847
848   my $loaded_colinfo = $self->result_source->columns_info;
849   $self->has_column_loaded($_) or delete $loaded_colinfo->{$_}
850     for keys %$loaded_colinfo;
851
852   my %cols_to_return = ( %{$self->{_column_data}}, %$loaded_colinfo );
853
854   unless ($ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}) {
855     for (keys %$loaded_colinfo) {
856       # if cached related_resultset is present assume this was a prefetch
857       if (
858         $loaded_colinfo->{$_}{_inflate_info}
859           and
860         defined $self->{related_resultsets}{$_}
861           and
862         defined $self->{related_resultsets}{$_}->get_cache
863       ) {
864         carp_unique(
865           "Returning prefetched 'filter' rels as part of get_inflated_columns() is deprecated and will "
866         . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
867         );
868         last;
869       }
870     }
871   }
872
873   map { $_ => (
874   (
875     ! exists $loaded_colinfo->{$_}
876       or
877     (
878       exists $loaded_colinfo->{$_}{accessor}
879         and
880       ! defined $loaded_colinfo->{$_}{accessor}
881     )
882   ) ? $self->get_column($_)
883     : $self->${ \(
884       defined $loaded_colinfo->{$_}{accessor}
885         ? $loaded_colinfo->{$_}{accessor}
886         : $_
887       )}
888   )} keys %cols_to_return;
889 }
890
891 sub _is_column_numeric {
892     my ($self, $column) = @_;
893
894     return undef unless $self->result_source->has_column($column);
895
896     my $colinfo = $self->result_source->column_info ($column);
897
898     # cache for speed (the object may *not* have a resultsource instance)
899     if (
900       ! defined $colinfo->{is_numeric}
901         and
902       my $storage = dbic_internal_try { $self->result_source->schema->storage }
903     ) {
904       $colinfo->{is_numeric} =
905         $storage->is_datatype_numeric ($colinfo->{data_type})
906           ? 1
907           : 0
908         ;
909     }
910
911     return $colinfo->{is_numeric};
912 }
913
914 =head2 set_column
915
916   $result->set_column($col => $val);
917
918 =over
919
920 =item Arguments: $columnname, $value
921
922 =item Return Value: $value
923
924 =back
925
926 Sets a raw column value. If the new value is different from the old one,
927 the column is marked as dirty for when you next call L</update>.
928
929 If passed an object or reference as a value, this method will happily
930 attempt to store it, and a later L</insert> or L</update> will try and
931 stringify/numify as appropriate. To set an object to be deflated
932 instead, see L</set_inflated_columns>, or better yet, use L</$column_accessor>.
933
934 =cut
935
936 sub set_column {
937   my ($self, $column, $new_value) = @_;
938
939   my $had_value = $self->has_column_loaded($column);
940   my $old_value = $self->get_column($column);
941
942   $new_value = $self->store_column($column, $new_value);
943
944   my $dirty =
945     $self->{_dirty_columns}{$column}
946       ||
947     ( $self->in_storage # no point tracking dirtyness on uninserted data
948       ? ! $self->_eq_column_values ($column, $old_value, $new_value)
949       : 1
950     )
951   ;
952
953   if ($dirty) {
954     # FIXME sadly the update code just checks for keys, not for their value
955     $self->{_dirty_columns}{$column} = 1;
956
957     # Clear out the relation/inflation cache related to this column
958     #
959     # FIXME - this is a quick *largely incorrect* hack, pending a more
960     # serious rework during the merge of single and filter rels
961     my $rel_names = $self->result_source->{_relationships};
962     for my $rel_name (keys %$rel_names) {
963
964       my $acc = $rel_names->{$rel_name}{attrs}{accessor} || '';
965
966       if ( $acc eq 'single' and $rel_names->{$rel_name}{attrs}{fk_columns}{$column} ) {
967         delete $self->{related_resultsets}{$rel_name};
968         delete $self->{_relationship_data}{$rel_name};
969         #delete $self->{_inflated_column}{$rel_name};
970       }
971       elsif ( $acc eq 'filter' and $rel_name eq $column) {
972         delete $self->{related_resultsets}{$rel_name};
973         #delete $self->{_relationship_data}{$rel_name};
974         delete $self->{_inflated_column}{$rel_name};
975       }
976     }
977
978     if (
979       # value change from something (even if NULL)
980       $had_value
981         and
982       # no storage - no storage-value
983       $self->in_storage
984         and
985       # no value already stored (multiple changes before commit to storage)
986       ! exists $self->{_column_data_in_storage}{$column}
987         and
988       $self->_track_storage_value($column)
989     ) {
990       $self->{_column_data_in_storage}{$column} = $old_value;
991     }
992   }
993
994   return $new_value;
995 }
996
997 sub _eq_column_values {
998   my ($self, $col, $old, $new) = @_;
999
1000   if (defined $old xor defined $new) {
1001     return 0;
1002   }
1003   elsif (not defined $old) {  # both undef
1004     return 1;
1005   }
1006   elsif (
1007     is_literal_value $old
1008       or
1009     is_literal_value $new
1010   ) {
1011     return 0;
1012   }
1013   elsif ($old eq $new) {
1014     return 1;
1015   }
1016   elsif ($self->_is_column_numeric($col)) {  # do a numeric comparison if datatype allows it
1017     return $old == $new;
1018   }
1019   else {
1020     return 0;
1021   }
1022 }
1023
1024 # returns a boolean indicating if the passed column should have its original
1025 # value tracked between column changes and commitment to storage
1026 sub _track_storage_value {
1027   my ($self, $col) = @_;
1028   return scalar grep
1029     { $col eq $_ }
1030     $self->result_source->primary_columns
1031   ;
1032 }
1033
1034 =head2 set_columns
1035
1036   $result->set_columns({ $col => $val, ... });
1037
1038 =over
1039
1040 =item Arguments: \%columndata
1041
1042 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1043
1044 =back
1045
1046 Sets multiple column, raw value pairs at once.
1047
1048 Works as L</set_column>.
1049
1050 =cut
1051
1052 sub set_columns {
1053   my ($self, $values) = @_;
1054   $self->set_column( $_, $values->{$_} ) for keys %$values;
1055   return $self;
1056 }
1057
1058 =head2 set_inflated_columns
1059
1060   $result->set_inflated_columns({ $col => $val, $rel_name => $obj, ... });
1061
1062 =over
1063
1064 =item Arguments: \%columndata
1065
1066 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1067
1068 =back
1069
1070 Sets more than one column value at once. Any inflated values are
1071 deflated and the raw values stored.
1072
1073 Any related values passed as Result objects, using the relation name as a
1074 key, are reduced to the appropriate foreign key values and stored. If
1075 instead of related result objects, a hashref of column, value data is
1076 passed, will create the related object first then store.
1077
1078 Will even accept arrayrefs of data as a value to a
1079 L<DBIx::Class::Relationship/has_many> key, and create the related
1080 objects if necessary.
1081
1082 Be aware that the input hashref might be edited in place, so don't rely
1083 on it being the same after a call to C<set_inflated_columns>. If you
1084 need to preserve the hashref, it is sufficient to pass a shallow copy
1085 to C<set_inflated_columns>, e.g. ( { %{ $href } } )
1086
1087 See also L<DBIx::Class::Relationship::Base/set_from_related>.
1088
1089 =cut
1090
1091 sub set_inflated_columns {
1092   my ( $self, $upd ) = @_;
1093   my $rsrc;
1094   foreach my $key (keys %$upd) {
1095     if (ref $upd->{$key}) {
1096       $rsrc ||= $self->result_source;
1097       my $info = $rsrc->relationship_info($key);
1098       my $acc_type = $info->{attrs}{accessor} || '';
1099
1100       if ($acc_type eq 'single') {
1101         my $rel_obj = delete $upd->{$key};
1102         $self->set_from_related($key => $rel_obj);
1103         $self->{_relationship_data}{$key} = $rel_obj;
1104       }
1105       elsif ($acc_type eq 'multi') {
1106         $self->throw_exception(
1107           "Recursive update is not supported over relationships of type '$acc_type' ($key)"
1108         );
1109       }
1110       elsif (
1111         $rsrc->has_column($key)
1112           and
1113         exists $rsrc->column_info($key)->{_inflate_info}
1114       ) {
1115         $self->set_inflated_column($key, delete $upd->{$key});
1116       }
1117     }
1118   }
1119   $self->set_columns($upd);
1120 }
1121
1122 =head2 copy
1123
1124   my $copy = $orig->copy({ change => $to, ... });
1125
1126 =over
1127
1128 =item Arguments: \%replacementdata
1129
1130 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass> copy
1131
1132 =back
1133
1134 Inserts a new row into the database, as a copy of the original
1135 object. If a hashref of replacement data is supplied, these will take
1136 precedence over data in the original. Also any columns which have
1137 the L<column info attribute|DBIx::Class::ResultSource/add_columns>
1138 C<< is_auto_increment => 1 >> are explicitly removed before the copy,
1139 so that the database can insert its own autoincremented values into
1140 the new object.
1141
1142 Relationships will be followed by the copy procedure B<only> if the
1143 relationship specifies a true value for its
1144 L<cascade_copy|DBIx::Class::Relationship::Base> attribute. C<cascade_copy>
1145 is set by default on C<has_many> relationships and unset on all others.
1146
1147 =cut
1148
1149 sub copy {
1150   my ($self, $changes) = @_;
1151   $changes ||= {};
1152   my $col_data = { $self->get_columns };
1153
1154   my $rsrc = $self->result_source;
1155
1156   my $colinfo = $rsrc->columns_info;
1157   foreach my $col (keys %$col_data) {
1158     delete $col_data->{$col}
1159       if ( ! $colinfo->{$col} or $colinfo->{$col}{is_auto_increment} );
1160   }
1161
1162   my $new = { _column_data => $col_data };
1163   bless $new, ref $self;
1164
1165   $new->result_source($rsrc);
1166   $new->set_inflated_columns($changes);
1167   $new->insert;
1168
1169   # Its possible we'll have 2 relations to the same Source. We need to make
1170   # sure we don't try to insert the same row twice else we'll violate unique
1171   # constraints
1172   my $rel_names_copied = {};
1173
1174   foreach my $rel_name ($rsrc->relationships) {
1175     my $rel_info = $rsrc->relationship_info($rel_name);
1176
1177     next unless $rel_info->{attrs}{cascade_copy};
1178
1179     my $foreign_vals;
1180     my $copied = $rel_names_copied->{ $rel_info->{source} } ||= {};
1181
1182     $copied->{$_->ID}++ or $_->copy(
1183
1184       $foreign_vals ||= $rsrc->_resolve_relationship_condition(
1185         infer_values_based_on => {},
1186         rel_name => $rel_name,
1187         self_result_object => $new,
1188
1189         self_alias => "\xFE", # irrelevant
1190         foreign_alias => "\xFF", # irrelevant,
1191       )->{inferred_values}
1192
1193     ) for $self->search_related($rel_name)->all;
1194   }
1195   return $new;
1196 }
1197
1198 =head2 store_column
1199
1200   $result->store_column($col => $val);
1201
1202 =over
1203
1204 =item Arguments: $columnname, $value
1205
1206 =item Return Value: The value sent to storage
1207
1208 =back
1209
1210 Set a raw value for a column without marking it as changed. This
1211 method is used internally by L</set_column> which you should probably
1212 be using.
1213
1214 This is the lowest level at which data is set on a result object,
1215 extend this method to catch all data setting methods.
1216
1217 =cut
1218
1219 sub store_column {
1220   my ($self, $column, $value) = @_;
1221   $self->throw_exception( "No such column '${column}' on " . ref $self )
1222     unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
1223   $self->throw_exception( "set_column called for ${column} without value" )
1224     if @_ < 3;
1225
1226   return $self->{_column_data}{$column} = $value
1227     unless length ref $value and my $vref = is_plain_value( $value );
1228
1229   # if we are dealing with a value/ref - there are a couple possibilities
1230   # unpack the underlying piece of data and stringify all objects explicitly
1231   # ( to accomodate { -value => ... } and guard against overloaded objects
1232   # with defined stringification AND fallback => 0 (ugh!)
1233   $self->{_column_data}{$column} = defined blessed $$vref
1234     ? "$$vref"
1235     : $$vref
1236   ;
1237 }
1238
1239 =head2 inflate_result
1240
1241   Class->inflate_result($result_source, \%me, \%prefetch?)
1242
1243 =over
1244
1245 =item Arguments: L<$result_source|DBIx::Class::ResultSource>, \%columndata, \%prefetcheddata
1246
1247 =item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
1248
1249 =back
1250
1251 All L<DBIx::Class::ResultSet> methods that retrieve data from the
1252 database and turn it into result objects call this method.
1253
1254 Extend this method in your Result classes to hook into this process,
1255 for example to rebless the result into a different class.
1256
1257 Reblessing can also be done more easily by setting C<result_class> in
1258 your Result class. See L<DBIx::Class::ResultSource/result_class>.
1259
1260 Different types of results can also be created from a particular
1261 L<DBIx::Class::ResultSet>, see L<DBIx::Class::ResultSet/result_class>.
1262
1263 =cut
1264
1265 sub inflate_result {
1266   my ($class, $rsrc, $me, $prefetch) = @_;
1267
1268   my $new = bless
1269     { _column_data => $me, _result_source => $rsrc },
1270     ref $class || $class
1271   ;
1272
1273   if ($prefetch) {
1274     for my $rel_name ( keys %$prefetch ) {
1275
1276       my $relinfo = $rsrc->relationship_info($rel_name) or do {
1277         my $err = sprintf
1278           "Inflation into non-existent relationship '%s' of '%s' requested",
1279           $rel_name,
1280           $rsrc->source_name,
1281         ;
1282         if (my ($colname) = sort { length($a) <=> length ($b) } keys %{$prefetch->{$rel_name}[0] || {}} ) {
1283           $err .= sprintf ", check the inflation specification (columns/as) ending in '...%s.%s'",
1284           $rel_name,
1285           $colname,
1286         }
1287
1288         $rsrc->throw_exception($err);
1289       };
1290
1291       $class->throw_exception("No accessor type declared for prefetched relationship '$rel_name'")
1292         unless $relinfo->{attrs}{accessor};
1293
1294       my $rel_rs = $new->related_resultset($rel_name);
1295
1296       my @rel_objects;
1297       if (
1298         @{ $prefetch->{$rel_name} || [] }
1299           and
1300         ref($prefetch->{$rel_name}) ne $DBIx::Class::ResultSource::RowParser::Util::null_branch_class
1301       ) {
1302
1303         if (ref $prefetch->{$rel_name}[0] eq 'ARRAY') {
1304           my $rel_rsrc = $rel_rs->result_source;
1305           my $rel_class = $rel_rs->result_class;
1306           my $rel_inflator = $rel_class->can('inflate_result');
1307           @rel_objects = map
1308             { $rel_class->$rel_inflator ( $rel_rsrc, @$_ ) }
1309             @{$prefetch->{$rel_name}}
1310           ;
1311         }
1312         else {
1313           @rel_objects = $rel_rs->result_class->inflate_result(
1314             $rel_rs->result_source, @{$prefetch->{$rel_name}}
1315           );
1316         }
1317       }
1318
1319       if ($relinfo->{attrs}{accessor} eq 'single') {
1320         $new->{_relationship_data}{$rel_name} = $rel_objects[0];
1321       }
1322       elsif ($relinfo->{attrs}{accessor} eq 'filter') {
1323         $new->{_inflated_column}{$rel_name} = $rel_objects[0];
1324       }
1325
1326       $rel_rs->set_cache(\@rel_objects);
1327     }
1328   }
1329
1330   $new->in_storage (1);
1331   return $new;
1332 }
1333
1334 =head2 update_or_insert
1335
1336   $result->update_or_insert
1337
1338 =over
1339
1340 =item Arguments: none
1341
1342 =item Return Value: Result of update or insert operation
1343
1344 =back
1345
1346 L</update>s the object if it's already in the database, according to
1347 L</in_storage>, else L</insert>s it.
1348
1349 =head2 insert_or_update
1350
1351   $obj->insert_or_update
1352
1353 Alias for L</update_or_insert>
1354
1355 =cut
1356
1357 sub insert_or_update { shift->update_or_insert(@_) }
1358
1359 sub update_or_insert {
1360   my $self = shift;
1361   return ($self->in_storage ? $self->update : $self->insert);
1362 }
1363
1364 =head2 is_changed
1365
1366   my @changed_col_names = $result->is_changed();
1367   if ($result->is_changed()) { ... }
1368
1369 =over
1370
1371 =item Arguments: none
1372
1373 =item Return Value: 0|1 or @columnnames
1374
1375 =back
1376
1377 In list context returns a list of columns with uncommited changes, or
1378 in scalar context returns a true value if there are uncommitted
1379 changes.
1380
1381 =cut
1382
1383 sub is_changed {
1384   return keys %{shift->{_dirty_columns} || {}};
1385 }
1386
1387 =head2 is_column_changed
1388
1389   if ($result->is_column_changed('col')) { ... }
1390
1391 =over
1392
1393 =item Arguments: $columname
1394
1395 =item Return Value: 0|1
1396
1397 =back
1398
1399 Returns a true value if the column has uncommitted changes.
1400
1401 =cut
1402
1403 sub is_column_changed {
1404   my( $self, $col ) = @_;
1405   return exists $self->{_dirty_columns}->{$col};
1406 }
1407
1408 =head2 result_source
1409
1410   my $resultsource = $result->result_source;
1411
1412 =over
1413
1414 =item Arguments: L<$result_source?|DBIx::Class::ResultSource>
1415
1416 =item Return Value: L<$result_source|DBIx::Class::ResultSource>
1417
1418 =back
1419
1420 Accessor to the L<DBIx::Class::ResultSource> this object was created from.
1421
1422 =cut
1423
1424 sub result_source {
1425   $_[0]->throw_exception( 'result_source can be called on instances only' )
1426     unless ref $_[0];
1427
1428   @_ > 1
1429     ? $_[0]->{_result_source} = $_[1]
1430
1431     # note this is a || not a ||=, the difference is important
1432     : $_[0]->{_result_source} || do {
1433         $_[0]->can('result_source_instance')
1434           ? $_[0]->result_source_instance
1435           : $_[0]->throw_exception(
1436             "No result source instance registered for @{[ ref $_[0] ]}, did you forget to call @{[ ref $_[0] ]}->table(...) ?"
1437           )
1438       }
1439   ;
1440 }
1441
1442 =head2 register_column
1443
1444   $column_info = { .... };
1445   $class->register_column($column_name, $column_info);
1446
1447 =over
1448
1449 =item Arguments: $columnname, \%columninfo
1450
1451 =item Return Value: not defined
1452
1453 =back
1454
1455 Registers a column on the class. If the column_info has an 'accessor'
1456 key, creates an accessor named after the value if defined; if there is
1457 no such key, creates an accessor with the same name as the column
1458
1459 The column_info attributes are described in
1460 L<DBIx::Class::ResultSource/add_columns>
1461
1462 =cut
1463
1464 sub register_column {
1465   my ($class, $col, $info) = @_;
1466   my $acc = $col;
1467   if (exists $info->{accessor}) {
1468     return unless defined $info->{accessor};
1469     $acc = [ $info->{accessor}, $col ];
1470   }
1471   $class->mk_group_accessors('column' => $acc);
1472 }
1473
1474 =head2 get_from_storage
1475
1476   my $copy = $result->get_from_storage($attrs)
1477
1478 =over
1479
1480 =item Arguments: \%attrs
1481
1482 =item Return Value: A Result object
1483
1484 =back
1485
1486 Fetches a fresh copy of the Result object from the database and returns it.
1487 Throws an exception if a proper WHERE clause identifying the database row
1488 can not be constructed (i.e. if the original object does not contain its
1489 entire
1490  L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
1491 ). If passed the \%attrs argument, will first apply these attributes to
1492 the resultset used to find the row.
1493
1494 This copy can then be used to compare to an existing result object, to
1495 determine if any changes have been made in the database since it was
1496 created.
1497
1498 To just update your Result object with any latest changes from the
1499 database, use L</discard_changes> instead.
1500
1501 The \%attrs argument should be compatible with
1502 L<DBIx::Class::ResultSet/ATTRIBUTES>.
1503
1504 =cut
1505
1506 sub get_from_storage {
1507     my $self = shift @_;
1508     my $attrs = shift @_;
1509     my $resultset = $self->result_source->resultset;
1510
1511     if(defined $attrs) {
1512       $resultset = $resultset->search(undef, $attrs);
1513     }
1514
1515     return $resultset->find($self->_storage_ident_condition);
1516 }
1517
1518 =head2 discard_changes
1519
1520   $result->discard_changes
1521
1522 =over
1523
1524 =item Arguments: none or $attrs
1525
1526 =item Return Value: self (updates object in-place)
1527
1528 =back
1529
1530 Re-selects the row from the database, losing any changes that had
1531 been made. Throws an exception if a proper C<WHERE> clause identifying
1532 the database row can not be constructed (i.e. if the original object
1533 does not contain its entire
1534 L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>).
1535
1536 This method can also be used to refresh from storage, retrieving any
1537 changes made since the row was last read from storage.
1538
1539 $attrs, if supplied, is expected to be a hashref of attributes suitable for passing as the
1540 second argument to C<< $resultset->search($cond, $attrs) >>;
1541
1542 Note: If you are using L<DBIx::Class::Storage::DBI::Replicated> as your
1543 storage, a default of
1544 L<< C<< { force_pool => 'master' } >>
1545 |DBIx::Class::Storage::DBI::Replicated/SYNOPSIS >>  is automatically set for
1546 you. Prior to C<< DBIx::Class 0.08109 >> (before 2010) one would have been
1547 required to explicitly wrap the entire operation in a transaction to guarantee
1548 that up-to-date results are read from the master database.
1549
1550 =cut
1551
1552 sub discard_changes {
1553   my ($self, $attrs) = @_;
1554   return unless $self->in_storage; # Don't reload if we aren't real!
1555
1556   # add a replication default to read from the master only
1557   $attrs = { force_pool => 'master', %{$attrs||{}} };
1558
1559   if( my $current_storage = $self->get_from_storage($attrs)) {
1560
1561     # Set $self to the current.
1562     %$self = %$current_storage;
1563
1564     # Avoid a possible infinite loop with
1565     # sub DESTROY { $_[0]->discard_changes }
1566     bless $current_storage, 'Do::Not::Exist';
1567
1568     return $self;
1569   }
1570   else {
1571     $self->in_storage(0);
1572     return $self;
1573   }
1574 }
1575
1576 =head2 throw_exception
1577
1578 See L<DBIx::Class::Schema/throw_exception>.
1579
1580 =cut
1581
1582 sub throw_exception {
1583   my $self=shift;
1584
1585   if (
1586     ref $self
1587       and
1588     my $rsrc = dbic_internal_try { $self->result_source_instance }
1589   ) {
1590     $rsrc->throw_exception(@_)
1591   }
1592   else {
1593     DBIx::Class::Exception->throw(@_);
1594   }
1595 }
1596
1597 =head2 id
1598
1599   my @pk = $result->id;
1600
1601 =over
1602
1603 =item Arguments: none
1604
1605 =item Returns: A list of primary key values
1606
1607 =back
1608
1609 Returns the primary key(s) for a row. Can't be called as a class method.
1610 Actually implemented in L<DBIx::Class::PK>
1611
1612 =head1 FURTHER QUESTIONS?
1613
1614 Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
1615
1616 =head1 COPYRIGHT AND LICENSE
1617
1618 This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1619 by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1620 redistribute it and/or modify it under the same terms as the
1621 L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
1622
1623 =cut
1624
1625 1;