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