1 package DBIx::Class::Row;
6 use base qw/DBIx::Class/;
7 use Carp::Clan qw/^DBIx::Class/;
11 __PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/);
15 DBIx::Class::Row - Basic row methods
21 This class is responsible for defining and doing basic operations on rows
22 derived from L<DBIx::Class::ResultSource> objects.
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.
37 my $row = My::Class->new(\%attrs);
39 my $row = $schema->resultset('MySource')->new(\%colsandvalues);
43 =item Arguments: \%attrs or \%colsandvalues
45 =item Returns: A Row object
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.
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.
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>.
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
67 For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
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
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)
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)
93 ->find_or_create($data);
95 # print STDERR "Neither, find_or_new\n";
96 return $self->find_or_new_related($relname, $data);
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);
112 # print STDERR "Assigning $self to $key\n";
113 $data->{$key} = $self;
116 # return 1 if $rel_source->pk_depends_on($key, $us);
122 my ($class, $attrs) = @_;
123 $class = ref $class if ref $class;
130 if (my $handle = delete $attrs->{-source_handle}) {
131 $new->_source_handle($handle);
135 if ($source = delete $attrs->{-result_source}) {
136 $new->result_source($source);
139 # print "Source ", $source->source_name, " is $new\n";
141 $new->throw_exception("attrs must be a hashref")
142 unless ref($attrs) eq 'HASH';
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;
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')
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);
163 $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
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";
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);
180 $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
181 $new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
183 $related->{$key} = $others;
184 # print STDERR "Related :", join(", ", keys %$related), "\n";
186 } elsif ($info && $info->{attrs}{accessor}
187 && $info->{attrs}{accessor} eq 'filter')
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);
194 $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage);
195 $inflated->{$key} = $rel_obj;
197 } elsif ($class->has_column($key)
198 && $class->column_info($key)->{_inflate_info}) {
199 $inflated->{$key} = $attrs->{$key};
202 # print STDERR "Done :", join(", ", keys %$related), "\n";
204 $new->throw_exception("No such column $key on $class")
205 unless $class->has_column($key);
206 $new->store_column($key => $attrs->{$key});
209 $new->{_relationship_data} = $related if $related;
210 $new->{_inflated_column} = $inflated if $inflated;
222 =item Arguments: none
224 =item Returns: The Row object
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>).
234 To fetch an uninserted row object, call
235 L<new|DBIx::Class::ResultSet/new> on a resultset.
237 This will also insert any uninserted, related objects held inside this
238 one, see L<DBIx::Class::ResultSet/create> for more details.
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")
253 # Check if we stored uninserted relobjs here in new()
254 my %related_stuff = (%{$self->{_relationship_data} || {}},
255 %{$self->{_inflated_column} || {}});
257 if(!$self->{_rel_in_storage}) {
259 # The guard will save us if we blow out of this scope via die
260 $rollback_guard = $source->storage->txn_scope_guard;
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.
266 my @pri = $self->primary_columns;
268 REL: foreach my $relname (keys %related_stuff) {
269 # print STDERR "Looking at: $relname\n";
270 my $rel_obj = $related_stuff{$relname};
272 next REL unless (Scalar::Util::blessed($rel_obj)
273 && $rel_obj->isa('DBIx::Class::Row'));
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 }
280 # print STDERR "$rel_obj\n";
281 # print STDERR "in_storage: ", $rel_obj->in_storage, "\n";
282 # print STDERR "Inserting $relname\n";
284 $self->set_from_related($relname, $rel_obj);
285 delete $related_stuff{$relname};
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";
298 my @auto_pri = grep {
299 !defined $self->get_column($_) ||
300 ref($self->get_column($_)) eq 'SCALAR'
301 } $self->primary_columns;
304 #$self->throw_exception( "More than one possible key found for auto-inc on ".ref $self )
305 # if defined $too_many;
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;
316 $self->{_dirty_columns} = {};
317 $self->{related_resultsets} = {};
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};
324 if (Scalar::Util::blessed($rel_obj)
325 && $rel_obj->isa('DBIx::Class::Row')) {
327 } elsif (ref $rel_obj eq 'ARRAY') {
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);
342 # print STDERR "No\n";
348 $rollback_guard->commit;
351 # $self->in_storage(1);
352 undef $self->{_orig_ident};
358 $row->in_storage; # Get value
359 $row->in_storage(1); # Set value
363 =item Arguments: none or 1|0
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>
374 Creating a row object using L<DBIx::Class::ResultSet/new>, or calling
375 L</delete> on one, sets it to false.
380 my ($self, $val) = @_;
381 $self->{_in_storage} = $val if @_ > 1;
382 return $self->{_in_storage};
387 $row->update(\%columns?)
391 =item Arguments: none or a hashref
393 =item Returns: The Row object
397 Throws an exception if the row object is not yet in the database,
398 according to L</in_storage>.
400 This method issues an SQL UPDATE query to commit any changes to the
401 object to the database if required.
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 } } )
410 If the values passed or any of the column values set on the object
411 contain scalar references, eg:
413 $row->last_modified(\'NOW()');
415 $row->update({ last_modified => \'NOW()' });
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>
423 $row->update()->discard_changes();
425 To determine before calling this method, which column values have
426 changed and will be updated, call L</get_dirty_columns>.
428 To check if any columns will be updated, call L</is_changed>.
430 To force a column to be updated, call L</make_column_dirty> before
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;
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
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");
454 $self->{_dirty_columns} = {};
455 $self->{related_resultsets} = {};
456 undef $self->{_orig_ident};
466 =item Arguments: none
468 =item Returns: The Row object
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.
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.
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.
487 See also L<DBIx::Class::ResultSet/delete>.
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};
502 $self->result_source->storage->delete(
503 $self->result_source, $ident_cond);
504 $self->in_storage(undef);
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;
517 my $val = $row->get_column($col);
521 =item Arguments: $columnname
523 =item Returns: The value of the column
527 Throws an exception if the column name given doesn't exist according
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.
533 If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
534 will be deflated and returned.
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.
541 To retrieve all loaded column values as a hash, use L</get_columns>.
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}));
553 $self->throw_exception( "No such column '${column}'" ) unless $self->has_column($column);
557 =head2 has_column_loaded
559 if ( $row->has_column_loaded($col) ) {
560 print "$col has been loaded from db";
565 =item Arguments: $columnname
571 Returns a true value if the column value has been loaded from the
572 database (or set locally).
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};
585 my %data = $row->get_columns;
589 =item Arguments: none
591 =item Returns: A hash of columnname, value pairs.
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>.
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};
608 return %{$self->{_column_data}};
611 =head2 get_dirty_columns
613 my %data = $row->get_dirty_columns;
617 =item Arguments: none
619 =item Returns: A hash of column, value pairs
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.
626 See L</get_columns> to fetch all column/value pairs.
630 sub get_dirty_columns {
632 return map { $_ => $self->{_column_data}{$_} }
633 keys %{$self->{_dirty_columns}};
636 =head2 make_column_dirty
638 $row->make_column_dirty($col)
642 =item Arguments: $columnname
644 =item Returns: undefined
648 Throws an exception if the column does not exist.
650 Marks a column as having been changed regardless of whether it has
654 sub make_column_dirty {
655 my ($self, $column) = @_;
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;
662 =head2 get_inflated_columns
664 my %inflated_data = $obj->get_inflated_columns;
668 =item Arguments: none
670 =item Returns: A hash of column, object|value pairs
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.
677 See L</get_columns> to get the uninflated values.
679 See L<DBIx::Class::InflateColumn> for how to setup inflation.
683 sub get_inflated_columns {
686 my $accessor = $self->column_info($_)->{'accessor'} || $_;
687 ($_ => $self->$accessor);
693 $row->set_column($col => $val);
697 =item Arguments: $columnname, $value
699 =item Returns: $value
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>.
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>.
714 my ($self, $column, $new_value) = @_;
716 $self->{_orig_ident} ||= $self->ident_condition;
717 my $old_value = $self->get_column($column);
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);
723 # XXX clear out the relation cache for this column
724 delete $self->{related_resultsets}{$column};
731 $row->set_columns({ $col => $val, ... });
735 =item Arguments: \%columndata
737 =item Returns: The Row object
741 Sets multiple column, raw value pairs at once.
743 Works as L</set_column>.
748 my ($self,$data) = @_;
749 foreach my $col (keys %$data) {
750 $self->set_column($col,$data->{$col});
755 =head2 set_inflated_columns
757 $row->set_inflated_columns({ $col => $val, $relname => $obj, ... });
761 =item Arguments: \%columndata
763 =item Returns: The Row object
767 Sets more than one column value at once. Any inflated values are
768 deflated and the raw values stored.
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.
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.
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 } } )
784 See also L<DBIx::Class::Relationship::Base/set_from_related>.
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')
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)"
805 elsif ($self->has_column($key)
806 && exists $self->column_info($key)->{_inflate_info})
808 $self->set_inflated_column($key, delete $upd->{$key});
812 $self->set_columns($upd);
817 my $copy = $orig->copy({ change => $to, ... });
821 =item Arguments: \%replacementdata
823 =item Returns: The Row object copy
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.
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.
839 my ($self, $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};
847 my $new = { _column_data => $col_data };
848 bless $new, ref $self;
850 $new->result_source($self->result_source);
851 $new->set_inflated_columns($changes);
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
857 my $rels_copied = {};
859 foreach my $rel ($self->result_source->relationships) {
860 my $rel_info = $self->result_source->relationship_info($rel);
862 next unless $rel_info->{attrs}{cascade_copy};
864 my $resolved = $self->result_source->resolve_condition(
865 $rel_info->{cond}, $rel, $new
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);
882 $row->store_column($col => $val);
886 =item Arguments: $columnname, $value
888 =item Returns: The value sent to storage
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
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.
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" )
907 return $self->{_column_data}{$column} = $value;
910 =head2 inflate_result
912 Class->inflate_result($result_source, \%me, \%prefetch?)
916 =item Arguments: $result_source, \%columndata, \%prefetcheddata
918 =item Returns: A Row object
922 All L<DBIx::Class::ResultSet> methods that retrieve data from the
923 database and turn it into row objects call this method.
925 Extend this method in your Result classes to hook into this process,
926 for example to rebless the result into a different class.
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>.
934 my ($class, $source, $me, $prefetch) = @_;
936 my ($source_handle) = $source;
938 if ($source->isa('DBIx::Class::ResultSourceHandle')) {
939 $source = $source_handle->resolve
941 $source_handle = $source->handle
945 _source_handle => $source_handle,
949 bless $new, (ref $class || $class);
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}")
957 if (ref($pre_val->[0]) eq 'ARRAY') { # multi
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) {
964 push(@pre_objects, $pre_source->result_class->inflate_result(
965 $pre_source, @{$pre_rec}));
967 $new->related_resultset($pre)->set_cache(\@pre_objects);
968 } elsif (defined $pre_val->[0]) {
970 unless ($pre_source->primary_columns == grep { exists $pre_val->[0]{$_}
971 and !defined $pre_val->[0]{$_} } $pre_source->primary_columns)
973 $fetched = $pre_source->result_class->inflate_result(
974 $pre_source, @{$pre_val});
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;
985 $class->throw_exception("Prefetch not supported with accessor '$accessor'");
992 =head2 update_or_insert
994 $row->update_or_insert
998 =item Arguments: none
1000 =item Returns: Result of update or insert operation
1004 L</Update>s the object if it's already in the database, according to
1005 L</in_storage>, else L</insert>s it.
1007 =head2 insert_or_update
1009 $obj->insert_or_update
1011 Alias for L</update_or_insert>
1015 sub insert_or_update { shift->update_or_insert(@_) }
1017 sub update_or_insert {
1019 return ($self->in_storage ? $self->update : $self->insert);
1024 my @changed_col_names = $row->is_changed();
1025 if ($row->is_changed()) { ... }
1029 =item Arguments: none
1031 =item Returns: 0|1 or @columnnames
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
1042 return keys %{shift->{_dirty_columns} || {}};
1045 =head2 is_column_changed
1047 if ($row->is_column_changed('col')) { ... }
1051 =item Arguments: $columname
1057 Returns a true value if the column has uncommitted changes.
1061 sub is_column_changed {
1062 my( $self, $col ) = @_;
1063 return exists $self->{_dirty_columns}->{$col};
1066 =head2 result_source
1068 my $resultsource = $row->result_source;
1072 =item Arguments: none
1074 =item Returns: a ResultSource instance
1078 Accessor to the L<DBIx::Class::ResultSource> this object was created from.
1086 $self->_source_handle($_[0]->handle);
1088 $self->_source_handle->resolve;
1092 =head2 register_column
1094 $column_info = { .... };
1095 $class->register_column($column_name, $column_info);
1099 =item Arguments: $columnname, \%columninfo
1101 =item Returns: undefined
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
1109 The column_info attributes are described in
1110 L<DBIx::Class::ResultSource/add_columns>
1114 sub register_column {
1115 my ($class, $col, $info) = @_;
1117 if (exists $info->{accessor}) {
1118 return unless defined $info->{accessor};
1119 $acc = [ $info->{accessor}, $col ];
1121 $class->mk_group_accessors('column' => $acc);
1124 =head2 get_from_storage
1126 my $copy = $row->get_from_storage($attrs)
1130 =item Arguments: \%attrs
1132 =item Returns: A Row object
1136 Fetches a fresh copy of the Row object from the database and returns it.
1138 If passed the \%attrs argument, will first apply these attributes to
1139 the resultset used to find the row.
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
1145 To just update your Row object with any latest changes from the
1146 database, use L</discard_changes> instead.
1148 The \%attrs argument should be compatible with
1149 L<DBIx::Class::ResultSet/ATTRIBUTES>.
1153 sub get_from_storage {
1154 my $self = shift @_;
1155 my $attrs = shift @_;
1156 my $resultset = $self->result_source->resultset;
1158 if(defined $attrs) {
1159 $resultset = $resultset->search(undef, $attrs);
1162 return $resultset->find($self->{_orig_ident} || $self->ident_condition);
1165 =head2 throw_exception
1167 See L<DBIx::Class::Schema/throw_exception>.
1171 sub throw_exception {
1173 if (ref $self && ref $self->result_source && $self->result_source->schema) {
1174 $self->result_source->schema->throw_exception(@_);
1186 =item Arguments: none
1188 =item Returns: A list of primary key values
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>
1195 =head2 discard_changes
1197 $row->discard_changes
1201 =item Arguments: none
1203 =item Returns: nothing (updates object in-place)
1207 Retrieves and sets the row object data from the database, losing any
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>
1220 Matt S. Trout <mst@shadowcatsystems.co.uk>
1224 You may distribute this code under the same terms as Perl itself.