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