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