1 package DBIx::Class::Row;
6 use base qw/DBIx::Class/;
7 use Carp::Clan qw/^DBIx::Class/;
13 $ENV{DBIC_MULTICREATE_DEBUG}
18 __PACKAGE__->mk_group_accessors('simple' => qw/_source_handle/);
22 DBIx::Class::Row - Basic row methods
28 This class is responsible for defining and doing basic operations on rows
29 derived from L<DBIx::Class::ResultSource> objects.
31 Row objects are returned from L<DBIx::Class::ResultSet>s using the
32 L<create|DBIx::Class::ResultSet/create>, L<find|DBIx::Class::ResultSet/find>,
33 L<next|DBIx::Class::ResultSet/next> and L<all|DBIx::Class::ResultSet/all> methods,
34 as well as invocations of 'single' (
35 L<belongs_to|DBIx::Class::Relationship/belongs_to>,
36 L<has_one|DBIx::Class::Relationship/has_one> or
37 L<might_have|DBIx::Class::Relationship/might_have>)
38 relationship accessors of L<DBIx::Class::Row> objects.
44 my $row = My::Class->new(\%attrs);
46 my $row = $schema->resultset('MySource')->new(\%colsandvalues);
50 =item Arguments: \%attrs or \%colsandvalues
52 =item Returns: A Row object
56 While you can create a new row object by calling C<new> directly on
57 this class, you are better off calling it on a
58 L<DBIx::Class::ResultSet> object.
60 When calling it directly, you will not get a complete, usable row
61 object until you pass or set the C<source_handle> attribute, to a
62 L<DBIx::Class::ResultSource> instance that is attached to a
63 L<DBIx::Class::Schema> with a valid connection.
65 C<$attrs> is a hashref of column name, value data. It can also contain
66 some other attributes such as the C<source_handle>.
68 Passing an object, or an arrayref of objects as a value will call
69 L<DBIx::Class::Relationship::Base/set_from_related> for you. When
70 passed a hashref or an arrayref of hashrefs as the value, these will
71 be turned into objects via new_related, and treated as if you had
74 For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
78 ## 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().
79 ## This only works because DBIC doesnt yet care to check whether the new_related objects have been passed all their mandatory columns
80 ## When doing the later insert, we need to make sure the PKs are set.
81 ## using _relationship_data in new and funky ways..
82 ## check Relationship::CascadeActions and Relationship::Accessor for compat
85 sub __new_related_find_or_new_helper {
86 my ($self, $relname, $data) = @_;
87 if ($self->__their_pk_needs_us($relname, $data)) {
88 return $self->result_source
89 ->related_source($relname)
93 if ($self->result_source->pk_depends_on($relname, $data)) {
94 return $self->result_source
95 ->related_source($relname)
97 ->find_or_create($data);
99 return $self->find_or_new_related($relname, $data);
102 sub __their_pk_needs_us { # this should maybe be in resultsource.
103 my ($self, $relname, $data) = @_;
104 my $source = $self->result_source;
105 my $reverse = $source->reverse_relationship_info($relname);
106 my $rel_source = $source->related_source($relname);
107 my $us = { $self->get_columns };
108 foreach my $key (keys %$reverse) {
109 # if their primary key depends on us, then we have to
110 # just create a result and we'll fill it out afterwards
111 return 1 if $rel_source->pk_depends_on($key, $us);
117 my ($class, $attrs) = @_;
118 $class = ref $class if ref $class;
125 if (my $handle = delete $attrs->{-source_handle}) {
126 $new->_source_handle($handle);
130 if ($source = delete $attrs->{-result_source}) {
131 $new->result_source($source);
134 if (my $related = delete $attrs->{-from_resultset}) {
135 @{$new->{_ignore_at_insert}={}}{@$related} = ();
139 $new->throw_exception("attrs must be a hashref")
140 unless ref($attrs) eq 'HASH';
142 my ($related,$inflated);
143 ## Pretend all the rels are actual objects, unset below if not, for insert() to fix
144 $new->{_rel_in_storage} = 1;
146 foreach my $key (keys %$attrs) {
147 if (ref $attrs->{$key}) {
148 ## Can we extract this lot to use with update(_or .. ) ?
149 confess "Can't do multi-create without result source" unless $source;
150 my $info = $source->relationship_info($key);
151 if ($info && $info->{attrs}{accessor}
152 && $info->{attrs}{accessor} eq 'single')
154 my $rel_obj = delete $attrs->{$key};
155 if(!Scalar::Util::blessed($rel_obj)) {
156 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
159 if ($rel_obj->in_storage) {
160 $new->set_from_related($key, $rel_obj);
162 $new->{_rel_in_storage} = 0;
163 MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj\n";
166 $related->{$key} = $rel_obj;
168 } elsif ($info && $info->{attrs}{accessor}
169 && $info->{attrs}{accessor} eq 'multi'
170 && ref $attrs->{$key} eq 'ARRAY') {
171 my $others = delete $attrs->{$key};
172 my $total = @$others;
174 foreach my $idx (0 .. $#$others) {
175 my $rel_obj = $others->[$idx];
176 if(!Scalar::Util::blessed($rel_obj)) {
177 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
180 if ($rel_obj->in_storage) {
181 $new->set_from_related($key, $rel_obj);
183 $new->{_rel_in_storage} = 0;
184 MULTICREATE_DEBUG and
185 warn "MC $new uninserted $key $rel_obj (${\($idx+1)} of $total)\n";
187 $new->set_from_related($key, $rel_obj) if $rel_obj->in_storage;
188 push(@objects, $rel_obj);
190 $related->{$key} = \@objects;
192 } elsif ($info && $info->{attrs}{accessor}
193 && $info->{attrs}{accessor} eq 'filter')
195 ## 'filter' should disappear and get merged in with 'single' above!
196 my $rel_obj = delete $attrs->{$key};
197 if(!Scalar::Util::blessed($rel_obj)) {
198 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
200 unless ($rel_obj->in_storage) {
201 $new->{_rel_in_storage} = 0;
202 MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj";
204 $inflated->{$key} = $rel_obj;
206 } elsif ($class->has_column($key)
207 && $class->column_info($key)->{_inflate_info}) {
208 $inflated->{$key} = $attrs->{$key};
212 $new->throw_exception("No such column $key on $class")
213 unless $class->has_column($key);
214 $new->store_column($key => $attrs->{$key});
217 $new->{_relationship_data} = $related if $related;
218 $new->{_inflated_column} = $inflated if $inflated;
230 =item Arguments: none
232 =item Returns: The Row object
236 Inserts an object previously created by L</new> into the database if
237 it isn't already in there. Returns the object itself. Requires the
238 object's result source to be set, or the class to have a
239 result_source_instance method. To insert an entirely new row into
240 the database, use C<create> (see L<DBIx::Class::ResultSet/create>).
242 To fetch an uninserted row object, call
243 L<new|DBIx::Class::ResultSet/new> on a resultset.
245 This will also insert any uninserted, related objects held inside this
246 one, see L<DBIx::Class::ResultSet/create> for more details.
252 return $self if $self->in_storage;
253 my $source = $self->result_source;
254 $source ||= $self->result_source($self->result_source_instance)
255 if $self->can('result_source_instance');
256 $self->throw_exception("No result_source set on this object; can't insert")
261 # Check if we stored uninserted relobjs here in new()
262 my %related_stuff = (%{$self->{_relationship_data} || {}},
263 %{$self->{_inflated_column} || {}});
265 if(!$self->{_rel_in_storage}) {
267 # The guard will save us if we blow out of this scope via die
268 $rollback_guard = $source->storage->txn_scope_guard;
270 ## Should all be in relationship_data, but we need to get rid of the
271 ## 'filter' reltype..
272 ## These are the FK rels, need their IDs for the insert.
274 my @pri = $self->primary_columns;
276 REL: foreach my $relname (keys %related_stuff) {
278 my $rel_obj = $related_stuff{$relname};
280 next REL unless (Scalar::Util::blessed($rel_obj)
281 && $rel_obj->isa('DBIx::Class::Row'));
283 next REL unless $source->pk_depends_on(
284 $relname, { $rel_obj->get_columns }
287 MULTICREATE_DEBUG and warn "MC $self pre-inserting $relname $rel_obj\n";
290 $self->set_from_related($relname, $rel_obj);
291 delete $related_stuff{$relname};
295 MULTICREATE_DEBUG and do {
296 no warnings 'uninitialized';
297 warn "MC $self inserting (".join(', ', $self->get_columns).")\n";
299 my $updated_cols = $source->storage->insert($source, { $self->get_columns });
300 foreach my $col (keys %$updated_cols) {
301 $self->store_column($col, $updated_cols->{$col});
305 my @auto_pri = grep {
306 !defined $self->get_column($_) ||
307 ref($self->get_column($_)) eq 'SCALAR'
308 } $self->primary_columns;
311 #$self->throw_exception( "More than one possible key found for auto-inc on ".ref $self )
312 # if defined $too_many;
313 MULTICREATE_DEBUG and warn "MC $self fetching missing PKs ".join(', ', @auto_pri)."\n";
314 my $storage = $self->result_source->storage;
315 $self->throw_exception( "Missing primary key but Storage doesn't support last_insert_id" )
316 unless $storage->can('last_insert_id');
317 my @ids = $storage->last_insert_id($self->result_source,@auto_pri);
318 $self->throw_exception( "Can't get last insert id" )
319 unless (@ids == @auto_pri);
320 $self->store_column($auto_pri[$_] => $ids[$_]) for 0 .. $#ids;
321 #use Data::Dumper; warn Dumper($self);
325 $self->{_dirty_columns} = {};
326 $self->{related_resultsets} = {};
328 if(!$self->{_rel_in_storage}) {
329 ## Now do the relationships that need our ID (has_many etc.)
330 foreach my $relname (keys %related_stuff) {
331 my $rel_obj = $related_stuff{$relname};
333 if (Scalar::Util::blessed($rel_obj)
334 && $rel_obj->isa('DBIx::Class::Row')) {
336 } elsif (ref $rel_obj eq 'ARRAY') {
340 my $reverse = $source->reverse_relationship_info($relname);
341 foreach my $obj (@cands) {
342 $obj->set_from_related($_, $self) for keys %$reverse;
343 my $them = { %{$obj->{_relationship_data} || {} }, $obj->get_inflated_columns };
344 if ($self->__their_pk_needs_us($relname, $them)) {
345 if (exists $self->{_ignore_at_insert}{$relname}) {
346 MULTICREATE_DEBUG and warn "MC $self skipping post-insert on $relname";
348 MULTICREATE_DEBUG and warn "MC $self re-creating $relname $obj";
349 my $re = $self->find_or_create_related($relname, $them);
351 MULTICREATE_DEBUG and warn "MC $self new $relname $obj";
354 MULTICREATE_DEBUG and warn "MC $self post-inserting $obj";
360 delete $self->{_ignore_at_insert};
361 $rollback_guard->commit;
364 $self->in_storage(1);
365 undef $self->{_orig_ident};
371 $row->in_storage; # Get value
372 $row->in_storage(1); # Set value
376 =item Arguments: none or 1|0
382 Indicates whether the object exists as a row in the database or
383 not. This is set to true when L<DBIx::Class::ResultSet/find>,
384 L<DBIx::Class::ResultSet/create> or L<DBIx::Class::ResultSet/insert>
387 Creating a row object using L<DBIx::Class::ResultSet/new>, or calling
388 L</delete> on one, sets it to false.
393 my ($self, $val) = @_;
394 $self->{_in_storage} = $val if @_ > 1;
395 return $self->{_in_storage};
400 $row->update(\%columns?)
404 =item Arguments: none or a hashref
406 =item Returns: The Row object
410 Throws an exception if the row object is not yet in the database,
411 according to L</in_storage>.
413 This method issues an SQL UPDATE query to commit any changes to the
414 object to the database if required.
416 Also takes an optional hashref of C<< column_name => value> >> pairs
417 to update on the object first. Be aware that the hashref will be
418 passed to C<set_inflated_columns>, which might edit it in place, so
419 don't rely on it being the same after a call to C<update>. If you
420 need to preserve the hashref, it is sufficient to pass a shallow copy
421 to C<update>, e.g. ( { %{ $href } } )
423 If the values passed or any of the column values set on the object
424 contain scalar references, eg:
426 $row->last_modified(\'NOW()');
428 $row->update({ last_modified => \'NOW()' });
430 The update will pass the values verbatim into SQL. (See
431 L<SQL::Abstract> docs). The values in your Row object will NOT change
432 as a result of the update call, if you want the object to be updated
433 with the actual values from the database, call L</discard_changes>
436 $row->update()->discard_changes();
438 To determine before calling this method, which column values have
439 changed and will be updated, call L</get_dirty_columns>.
441 To check if any columns will be updated, call L</is_changed>.
443 To force a column to be updated, call L</make_column_dirty> before
449 my ($self, $upd) = @_;
450 $self->throw_exception( "Not in database" ) unless $self->in_storage;
451 my $ident_cond = $self->ident_condition;
452 $self->throw_exception("Cannot safely update a row in a PK-less table")
453 if ! keys %$ident_cond;
455 $self->set_inflated_columns($upd) if $upd;
456 my %to_update = $self->get_dirty_columns;
457 return $self unless keys %to_update;
458 my $rows = $self->result_source->storage->update(
459 $self->result_source, \%to_update,
460 $self->{_orig_ident} || $ident_cond
463 $self->throw_exception( "Can't update ${self}: row not found" );
464 } elsif ($rows > 1) {
465 $self->throw_exception("Can't update ${self}: updated more than one row");
467 $self->{_dirty_columns} = {};
468 $self->{related_resultsets} = {};
469 undef $self->{_orig_ident};
479 =item Arguments: none
481 =item Returns: The Row object
485 Throws an exception if the object is not in the database according to
486 L</in_storage>. Runs an SQL DELETE statement using the primary key
487 values to locate the row.
489 The object is still perfectly usable, but L</in_storage> will
490 now return 0 and the object must be reinserted using L</insert>
491 before it can be used to L</update> the row again.
493 If you delete an object in a class with a C<has_many> relationship, an
494 attempt is made to delete all the related objects as well. To turn
495 this behaviour off, pass C<< cascade_delete => 0 >> in the C<$attr>
496 hashref of the relationship, see L<DBIx::Class::Relationship>. Any
497 database-level cascade or restrict will take precedence over a
498 DBIx-Class-based cascading delete.
500 If you delete an object within a txn_do() (see L<DBIx::Class::Storage/txn_do>)
501 and the transaction subsequently fails, the row object will remain marked as
502 not being in storage. If you know for a fact that the object is still in
503 storage (i.e. by inspecting the cause of the transaction's failure), you can
504 use C<< $obj->in_storage(1) >> to restore consistency between the object and
505 the database. This would allow a subsequent C<< $obj->delete >> to work
508 See also L<DBIx::Class::ResultSet/delete>.
515 $self->throw_exception( "Not in database" ) unless $self->in_storage;
516 my $ident_cond = $self->{_orig_ident} || $self->ident_condition;
517 $self->throw_exception("Cannot safely delete a row in a PK-less table")
518 if ! keys %$ident_cond;
519 foreach my $column (keys %$ident_cond) {
520 $self->throw_exception("Can't delete the object unless it has loaded the primary keys")
521 unless exists $self->{_column_data}{$column};
523 $self->result_source->storage->delete(
524 $self->result_source, $ident_cond);
525 $self->in_storage(undef);
527 $self->throw_exception("Can't do class delete without a ResultSource instance")
528 unless $self->can('result_source_instance');
529 my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? { %{pop(@_)} } : {};
530 my $query = ref $_[0] eq 'HASH' ? $_[0] : {@_};
531 $self->result_source_instance->resultset->search(@_)->delete;
538 my $val = $row->get_column($col);
542 =item Arguments: $columnname
544 =item Returns: The value of the column
548 Throws an exception if the column name given doesn't exist according
551 Returns a raw column value from the row object, if it has already
552 been fetched from the database or set by an accessor.
554 If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
555 will be deflated and returned.
557 Note that if you used the C<columns> or the C<select/as>
558 L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
559 which C<$row> was derived, and B<did not include> C<$columnname> in the list,
560 this method will return C<undef> even if the database contains some value.
562 To retrieve all loaded column values as a hash, use L</get_columns>.
567 my ($self, $column) = @_;
568 $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
569 return $self->{_column_data}{$column} if exists $self->{_column_data}{$column};
570 if (exists $self->{_inflated_column}{$column}) {
571 return $self->store_column($column,
572 $self->_deflated_column($column, $self->{_inflated_column}{$column}));
574 $self->throw_exception( "No such column '${column}'" ) unless $self->has_column($column);
578 =head2 has_column_loaded
580 if ( $row->has_column_loaded($col) ) {
581 print "$col has been loaded from db";
586 =item Arguments: $columnname
592 Returns a true value if the column value has been loaded from the
593 database (or set locally).
597 sub has_column_loaded {
598 my ($self, $column) = @_;
599 $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
600 return 1 if exists $self->{_inflated_column}{$column};
601 return exists $self->{_column_data}{$column};
606 my %data = $row->get_columns;
610 =item Arguments: none
612 =item Returns: A hash of columnname, value pairs.
616 Returns all loaded column data as a hash, containing raw values. To
617 get just one value for a particular column, use L</get_column>.
623 if (exists $self->{_inflated_column}) {
624 foreach my $col (keys %{$self->{_inflated_column}}) {
625 $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}))
626 unless exists $self->{_column_data}{$col};
629 return %{$self->{_column_data}};
632 =head2 get_dirty_columns
634 my %data = $row->get_dirty_columns;
638 =item Arguments: none
640 =item Returns: A hash of column, value pairs
644 Only returns the column, value pairs for those columns that have been
645 changed on this object since the last L</update> or L</insert> call.
647 See L</get_columns> to fetch all column/value pairs.
651 sub get_dirty_columns {
653 return map { $_ => $self->{_column_data}{$_} }
654 keys %{$self->{_dirty_columns}};
657 =head2 make_column_dirty
659 $row->make_column_dirty($col)
663 =item Arguments: $columnname
665 =item Returns: undefined
669 Throws an exception if the column does not exist.
671 Marks a column as having been changed regardless of whether it has
675 sub make_column_dirty {
676 my ($self, $column) = @_;
678 $self->throw_exception( "No such column '${column}'" )
679 unless exists $self->{_column_data}{$column} || $self->has_column($column);
680 $self->{_dirty_columns}{$column} = 1;
683 =head2 get_inflated_columns
685 my %inflated_data = $obj->get_inflated_columns;
689 =item Arguments: none
691 =item Returns: A hash of column, object|value pairs
695 Returns a hash of all column keys and associated values. Values for any
696 columns set to use inflation will be inflated and returns as objects.
698 See L</get_columns> to get the uninflated values.
700 See L<DBIx::Class::InflateColumn> for how to setup inflation.
704 sub get_inflated_columns {
707 my $accessor = $self->column_info($_)->{'accessor'} || $_;
708 ($_ => $self->$accessor);
714 $row->set_column($col => $val);
718 =item Arguments: $columnname, $value
720 =item Returns: $value
724 Sets a raw column value. If the new value is different from the old one,
725 the column is marked as dirty for when you next call L</update>.
727 If passed an object or reference as a value, this method will happily
728 attempt to store it, and a later L</insert> or L</update> will try and
729 stringify/numify as appropriate. To set an object to be deflated
730 instead, see L</set_inflated_columns>.
735 my ($self, $column, $new_value) = @_;
737 $self->{_orig_ident} ||= $self->ident_condition;
738 my $old_value = $self->get_column($column);
740 $self->store_column($column, $new_value);
741 $self->{_dirty_columns}{$column} = 1
742 if (defined $old_value xor defined $new_value) || (defined $old_value && $old_value ne $new_value);
744 # XXX clear out the relation cache for this column
745 delete $self->{related_resultsets}{$column};
752 $row->set_columns({ $col => $val, ... });
756 =item Arguments: \%columndata
758 =item Returns: The Row object
762 Sets multiple column, raw value pairs at once.
764 Works as L</set_column>.
769 my ($self,$data) = @_;
770 foreach my $col (keys %$data) {
771 $self->set_column($col,$data->{$col});
776 =head2 set_inflated_columns
778 $row->set_inflated_columns({ $col => $val, $relname => $obj, ... });
782 =item Arguments: \%columndata
784 =item Returns: The Row object
788 Sets more than one column value at once. Any inflated values are
789 deflated and the raw values stored.
791 Any related values passed as Row objects, using the relation name as a
792 key, are reduced to the appropriate foreign key values and stored. If
793 instead of related row objects, a hashref of column, value data is
794 passed, will create the related object first then store.
796 Will even accept arrayrefs of data as a value to a
797 L<DBIx::Class::Relationship/has_many> key, and create the related
798 objects if necessary.
800 Be aware that the input hashref might be edited in place, so dont rely
801 on it being the same after a call to C<set_inflated_columns>. If you
802 need to preserve the hashref, it is sufficient to pass a shallow copy
803 to C<set_inflated_columns>, e.g. ( { %{ $href } } )
805 See also L<DBIx::Class::Relationship::Base/set_from_related>.
809 sub set_inflated_columns {
810 my ( $self, $upd ) = @_;
811 foreach my $key (keys %$upd) {
812 if (ref $upd->{$key}) {
813 my $info = $self->relationship_info($key);
814 if ($info && $info->{attrs}{accessor}
815 && $info->{attrs}{accessor} eq 'single')
817 my $rel = delete $upd->{$key};
818 $self->set_from_related($key => $rel);
819 $self->{_relationship_data}{$key} = $rel;
820 } elsif ($info && $info->{attrs}{accessor}
821 && $info->{attrs}{accessor} eq 'multi') {
822 $self->throw_exception(
823 "Recursive update is not supported over relationships of type multi ($key)"
826 elsif ($self->has_column($key)
827 && exists $self->column_info($key)->{_inflate_info})
829 $self->set_inflated_column($key, delete $upd->{$key});
833 $self->set_columns($upd);
838 my $copy = $orig->copy({ change => $to, ... });
842 =item Arguments: \%replacementdata
844 =item Returns: The Row object copy
848 Inserts a new row into the database, as a copy of the original
849 object. If a hashref of replacement data is supplied, these will take
850 precedence over data in the original.
852 If the row has related objects in a
853 L<DBIx::Class::Relationship/has_many> then those objects may be copied
854 too depending on the L<cascade_copy|DBIx::Class::Relationship>
855 relationship attribute.
860 my ($self, $changes) = @_;
862 my $col_data = { %{$self->{_column_data}} };
863 foreach my $col (keys %$col_data) {
864 delete $col_data->{$col}
865 if $self->result_source->column_info($col)->{is_auto_increment};
868 my $new = { _column_data => $col_data };
869 bless $new, ref $self;
871 $new->result_source($self->result_source);
872 $new->set_inflated_columns($changes);
875 # Its possible we'll have 2 relations to the same Source. We need to make
876 # sure we don't try to insert the same row twice esle we'll violate unique
878 my $rels_copied = {};
880 foreach my $rel ($self->result_source->relationships) {
881 my $rel_info = $self->result_source->relationship_info($rel);
883 next unless $rel_info->{attrs}{cascade_copy};
885 my $resolved = $self->result_source->resolve_condition(
886 $rel_info->{cond}, $rel, $new
889 my $copied = $rels_copied->{ $rel_info->{source} } ||= {};
890 foreach my $related ($self->search_related($rel)) {
891 my $id_str = join("\0", $related->id);
892 next if $copied->{$id_str};
893 $copied->{$id_str} = 1;
894 my $rel_copy = $related->copy($resolved);
903 $row->store_column($col => $val);
907 =item Arguments: $columnname, $value
909 =item Returns: The value sent to storage
913 Set a raw value for a column without marking it as changed. This
914 method is used internally by L</set_column> which you should probably
917 This is the lowest level at which data is set on a row object,
918 extend this method to catch all data setting methods.
923 my ($self, $column, $value) = @_;
924 $self->throw_exception( "No such column '${column}'" )
925 unless exists $self->{_column_data}{$column} || $self->has_column($column);
926 $self->throw_exception( "set_column called for ${column} without value" )
928 return $self->{_column_data}{$column} = $value;
931 =head2 inflate_result
933 Class->inflate_result($result_source, \%me, \%prefetch?)
937 =item Arguments: $result_source, \%columndata, \%prefetcheddata
939 =item Returns: A Row object
943 All L<DBIx::Class::ResultSet> methods that retrieve data from the
944 database and turn it into row objects call this method.
946 Extend this method in your Result classes to hook into this process,
947 for example to rebless the result into a different class.
949 Reblessing can also be done more easily by setting C<result_class> in
950 your Result class. See L<DBIx::Class::ResultSource/result_class>.
955 my ($class, $source, $me, $prefetch) = @_;
957 my ($source_handle) = $source;
959 if ($source->isa('DBIx::Class::ResultSourceHandle')) {
960 $source = $source_handle->resolve
962 $source_handle = $source->handle
966 _source_handle => $source_handle,
970 bless $new, (ref $class || $class);
973 foreach my $pre (keys %{$prefetch||{}}) {
974 my $pre_val = $prefetch->{$pre};
975 my $pre_source = $source->related_source($pre);
976 $class->throw_exception("Can't prefetch non-existent relationship ${pre}")
978 if (ref($pre_val->[0]) eq 'ARRAY') { # multi
980 foreach my $pre_rec (@$pre_val) {
981 unless ($pre_source->primary_columns == grep { exists $pre_rec->[0]{$_}
982 and defined $pre_rec->[0]{$_} } $pre_source->primary_columns) {
985 push(@pre_objects, $pre_source->result_class->inflate_result(
986 $pre_source, @{$pre_rec}));
988 $new->related_resultset($pre)->set_cache(\@pre_objects);
989 } elsif (defined $pre_val->[0]) {
991 unless ($pre_source->primary_columns == grep { exists $pre_val->[0]{$_}
992 and !defined $pre_val->[0]{$_} } $pre_source->primary_columns)
994 $fetched = $pre_source->result_class->inflate_result(
995 $pre_source, @{$pre_val});
997 $new->related_resultset($pre)->set_cache([ $fetched ]);
998 my $accessor = $source->relationship_info($pre)->{attrs}{accessor};
999 $class->throw_exception("No accessor for prefetched $pre")
1000 unless defined $accessor;
1001 if ($accessor eq 'single') {
1002 $new->{_relationship_data}{$pre} = $fetched;
1003 } elsif ($accessor eq 'filter') {
1004 $new->{_inflated_column}{$pre} = $fetched;
1006 $class->throw_exception("Prefetch not supported with accessor '$accessor'");
1013 =head2 update_or_insert
1015 $row->update_or_insert
1019 =item Arguments: none
1021 =item Returns: Result of update or insert operation
1025 L</Update>s the object if it's already in the database, according to
1026 L</in_storage>, else L</insert>s it.
1028 =head2 insert_or_update
1030 $obj->insert_or_update
1032 Alias for L</update_or_insert>
1036 sub insert_or_update { shift->update_or_insert(@_) }
1038 sub update_or_insert {
1040 return ($self->in_storage ? $self->update : $self->insert);
1045 my @changed_col_names = $row->is_changed();
1046 if ($row->is_changed()) { ... }
1050 =item Arguments: none
1052 =item Returns: 0|1 or @columnnames
1056 In list context returns a list of columns with uncommited changes, or
1057 in scalar context returns a true value if there are uncommitted
1063 return keys %{shift->{_dirty_columns} || {}};
1066 =head2 is_column_changed
1068 if ($row->is_column_changed('col')) { ... }
1072 =item Arguments: $columname
1078 Returns a true value if the column has uncommitted changes.
1082 sub is_column_changed {
1083 my( $self, $col ) = @_;
1084 return exists $self->{_dirty_columns}->{$col};
1087 =head2 result_source
1089 my $resultsource = $row->result_source;
1093 =item Arguments: none
1095 =item Returns: a ResultSource instance
1099 Accessor to the L<DBIx::Class::ResultSource> this object was created from.
1107 $self->_source_handle($_[0]->handle);
1109 $self->_source_handle->resolve;
1113 =head2 register_column
1115 $column_info = { .... };
1116 $class->register_column($column_name, $column_info);
1120 =item Arguments: $columnname, \%columninfo
1122 =item Returns: undefined
1126 Registers a column on the class. If the column_info has an 'accessor'
1127 key, creates an accessor named after the value if defined; if there is
1128 no such key, creates an accessor with the same name as the column
1130 The column_info attributes are described in
1131 L<DBIx::Class::ResultSource/add_columns>
1135 sub register_column {
1136 my ($class, $col, $info) = @_;
1138 if (exists $info->{accessor}) {
1139 return unless defined $info->{accessor};
1140 $acc = [ $info->{accessor}, $col ];
1142 $class->mk_group_accessors('column' => $acc);
1145 =head2 get_from_storage
1147 my $copy = $row->get_from_storage($attrs)
1151 =item Arguments: \%attrs
1153 =item Returns: A Row object
1157 Fetches a fresh copy of the Row object from the database and returns it.
1159 If passed the \%attrs argument, will first apply these attributes to
1160 the resultset used to find the row.
1162 This copy can then be used to compare to an existing row object, to
1163 determine if any changes have been made in the database since it was
1166 To just update your Row object with any latest changes from the
1167 database, use L</discard_changes> instead.
1169 The \%attrs argument should be compatible with
1170 L<DBIx::Class::ResultSet/ATTRIBUTES>.
1174 sub get_from_storage {
1175 my $self = shift @_;
1176 my $attrs = shift @_;
1177 my $resultset = $self->result_source->resultset;
1179 if(defined $attrs) {
1180 $resultset = $resultset->search(undef, $attrs);
1183 return $resultset->find($self->{_orig_ident} || $self->ident_condition);
1186 =head2 throw_exception
1188 See L<DBIx::Class::Schema/throw_exception>.
1192 sub throw_exception {
1194 if (ref $self && ref $self->result_source && $self->result_source->schema) {
1195 $self->result_source->schema->throw_exception(@_);
1207 =item Arguments: none
1209 =item Returns: A list of primary key values
1213 Returns the primary key(s) for a row. Can't be called as a class method.
1214 Actually implemented in L<DBIx::Class::PK>
1216 =head2 discard_changes
1218 $row->discard_changes
1222 =item Arguments: none
1224 =item Returns: nothing (updates object in-place)
1228 Retrieves and sets the row object data from the database, losing any
1231 This method can also be used to refresh from storage, retrieving any
1232 changes made since the row was last read from storage. Actually
1233 implemented in L<DBIx::Class::PK>
1241 Matt S. Trout <mst@shadowcatsystems.co.uk>
1245 You may distribute this code under the same terms as Perl itself.