1 package DBIx::Class::Row;
8 use base qw/DBIx::Class/;
10 __PACKAGE__->load_components(qw/AccessorGroup/);
12 __PACKAGE__->mk_group_accessors('simple' => 'result_source');
16 DBIx::Class::Row - Basic row methods
22 This class is responsible for defining and doing basic operations on rows
23 derived from L<DBIx::Class::Table> objects.
29 my $obj = My::Class->new($attrs);
31 Creates a new row object from column => value mappings passed as a hash ref
36 my ($class, $attrs) = @_;
37 $class = ref $class if ref $class;
38 my $new = bless({ _column_data => { } }, $class);
40 $new->throw("attrs must be a hashref" ) unless ref($attrs) eq 'HASH';
41 while (my ($k, $v) = each %{$attrs}) {
42 croak "No such column $k on $class" unless $class->has_column($k);
43 $new->store_column($k => $v);
53 Inserts an object into the database if it isn't already in there. Returns
54 the object itself. Requires the object's result source to be set, or the
55 class to have a result_source_instance method.
61 return $self if $self->in_storage;
62 $self->{result_source} ||= $self->result_source_instance
63 if $self->can('result_source_instance');
64 my $source = $self->{result_source};
65 croak "No result_source set on this object; can't insert" unless $source;
66 #use Data::Dumper; warn Dumper($self);
67 $source->storage->insert($source->from, { $self->get_columns });
69 $self->{_dirty_columns} = {};
75 $obj->in_storage; # Get value
76 $obj->in_storage(1); # Set value
78 Indicated whether the object exists as a row in the database or not
83 my ($self, $val) = @_;
84 $self->{_in_storage} = $val if @_ > 1;
85 return $self->{_in_storage};
92 Must be run on an object that is already in the database; issues an SQL
93 UPDATE query to commit any changes to the object to the db if required.
98 my ($self, $upd) = @_;
99 $self->throw( "Not in database" ) unless $self->in_storage;
100 my %to_update = $self->get_dirty_columns;
101 return $self unless keys %to_update;
102 my $rows = $self->result_source->storage->update(
103 $self->result_source->from, \%to_update, $self->ident_condition);
105 $self->throw( "Can't update ${self}: row not found" );
106 } elsif ($rows > 1) {
107 $self->throw("Can't update ${self}: updated more than one row");
109 $self->{_dirty_columns} = {};
117 Deletes the object from the database. The object is still perfectly usable
118 accessor-wise etc. but ->in_storage will now return 0 and the object must
119 be re ->insert'ed before it can be ->update'ed
126 $self->throw( "Not in database" ) unless $self->in_storage;
127 $self->result_source->storage->delete(
128 $self->result_source->from, $self->ident_condition);
129 $self->in_storage(undef);
131 croak "Can't do class delete without a ResultSource instance"
132 unless $self->can('result_source_instance');
134 if (@_ > 1 && ref $_[$#_] eq 'HASH') {
135 $attrs = { %{ pop(@_) } };
137 my $query = (ref $_[0] eq 'HASH' ? $_[0] : {@_});
138 $self->result_source_instance->resultset->search(@_)->delete;
145 my $val = $obj->get_column($col);
147 Gets a column value from a row object. Currently, does not do
148 any queries; the column must have already been fetched from
149 the database and stored in the object.
154 my ($self, $column) = @_;
155 $self->throw( "Can't fetch data as class method" ) unless ref $self;
156 return $self->{_column_data}{$column}
157 if exists $self->{_column_data}{$column};
158 $self->throw( "No such column '${column}'" ) unless $self->has_column($column);
164 my %data = $obj->get_columns;
166 Does C<get_column>, for all column values at once.
172 return %{$self->{_column_data}};
175 =head2 get_dirty_columns
177 my %data = $obj->get_dirty_columns;
179 Identical to get_columns but only returns those that have been changed.
183 sub get_dirty_columns {
185 return map { $_ => $self->{_column_data}{$_} }
186 keys %{$self->{_dirty_columns}};
191 $obj->set_column($col => $val);
193 Sets a column value. If the new value is different from the old one,
194 the column is marked as dirty for when you next call $obj->update.
201 my $old = $self->get_column($column);
202 my $ret = $self->store_column(@_);
203 $self->{_dirty_columns}{$column} = 1
204 if (defined $old ^ defined $ret) || (defined $old && $old ne $ret);
210 my $copy = $orig->set_columns({ $col => $val, ... });
212 Sets more than one column value at once.
217 my ($self,$data) = @_;
218 while (my ($col,$val) = each %$data) {
219 $self->set_column($col,$val);
226 my $copy = $orig->copy({ change => $to, ... });
228 Inserts a new row with the specified changes.
233 my ($self, $changes) = @_;
234 my $new = bless({ _column_data => { %{$self->{_column_data}}} }, ref $self);
235 $new->set_column($_ => $changes->{$_}) for keys %$changes;
241 $obj->store_column($col => $val);
243 Sets a column value without marking it as dirty.
248 my ($self, $column, $value) = @_;
249 $self->throw( "No such column '${column}'" )
250 unless exists $self->{_column_data}{$column} || $self->has_column($column);
251 $self->throw( "set_column called for ${column} without value" )
253 return $self->{_column_data}{$column} = $value;
256 =head2 inflate_result
258 Class->inflate_result($result_source, \%me, \%prefetch?)
260 Called by ResultSet to inflate a result from storage
265 my ($class, $source, $me, $prefetch) = @_;
266 #use Data::Dumper; print Dumper(@_);
267 my $new = bless({ result_source => $source,
271 ref $class || $class);
273 PRE: foreach my $pre (keys %{$prefetch||{}}) {
274 my $pre_source = $source->related_source($pre);
275 croak "Can't prefetch non-existant relationship ${pre}" unless $pre_source;
276 my $fetched = $pre_source->result_class->inflate_result(
277 $pre_source, @{$prefetch->{$pre}});
278 my $accessor = $source->relationship_info($pre)->{attrs}{accessor};
279 $class->throw("No accessor for prefetched $pre")
280 unless defined $accessor;
281 PRIMARY: foreach my $pri ($pre_source->primary_columns) {
282 unless (defined $fetched->get_column($pri)) {
287 if ($accessor eq 'single') {
288 $new->{_relationship_data}{$pre} = $fetched;
289 } elsif ($accessor eq 'filter') {
290 $new->{_inflated_column}{$pre} = $fetched;
292 $class->throw("Don't know how to store prefetched $pre");
298 =head2 insert_or_update
300 $obj->insert_or_update
302 Updates the object if it's already in the db, else inserts it.
306 sub insert_or_update {
308 return ($self->in_storage ? $self->update : $self->insert);
313 my @changed_col_names = $obj->is_changed
318 return keys %{shift->{_dirty_columns} || {}};
323 Accessor to the ResultSource this object was created from
325 =head2 register_column($column, $column_info)
327 Registers a column on the class and creates an accessor for it
331 sub register_column {
332 my ($class, $col, $info) = @_;
333 $class->mk_group_accessors('column' => $col);
340 Matt S. Trout <mst@shadowcatsystems.co.uk>
344 You may distribute this code under the same terms as Perl itself.