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