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