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