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