Reduce duplicate ->result_source calls where sensible
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
CommitLineData
7624b19f 1package DBIx::Class::Row;
2
3use strict;
4use warnings;
5
1edd1722 6use base qw/DBIx::Class/;
1a58752c 7
6298a324 8use Scalar::Util 'blessed';
ddcc02d1 9use DBIx::Class::_Util 'dbic_internal_try';
6dd43920 10use DBIx::Class::Carp;
f6d731aa 11use SQL::Abstract qw( is_literal_value is_plain_value );
1edd1722 12
0d5d1f12 13###
14### Internal method
15### Do not use
16###
e0cdf2cb 17BEGIN {
18 *MULTICREATE_DEBUG =
19 $ENV{DBIC_MULTICREATE_DEBUG}
20 ? sub () { 1 }
21 : sub () { 0 };
22}
23
9c1700e3 24use namespace::clean;
8c49f629 25
4c8ef945 26__PACKAGE__->mk_group_accessors ( simple => [ in_storage => '_in_storage' ] );
27
75d07914 28=head1 NAME
7624b19f 29
30DBIx::Class::Row - Basic row methods
31
32=head1 SYNOPSIS
33
34=head1 DESCRIPTION
35
36This class is responsible for defining and doing basic operations on rows
1ea77c14 37derived from L<DBIx::Class::ResultSource> objects.
7624b19f 38
fb13a49f 39Result objects are returned from L<DBIx::Class::ResultSet>s using the
ea36f4e4 40L<create|DBIx::Class::ResultSet/create>, L<find|DBIx::Class::ResultSet/find>,
41L<next|DBIx::Class::ResultSet/next> and L<all|DBIx::Class::ResultSet/all> methods,
42as well as invocations of 'single' (
43L<belongs_to|DBIx::Class::Relationship/belongs_to>,
44L<has_one|DBIx::Class::Relationship/has_one> or
45L<might_have|DBIx::Class::Relationship/might_have>)
fb13a49f 46relationship accessors of L<Result|DBIx::Class::Manual::ResultClass> objects.
a2531bf2 47
93711422 48=head1 NOTE
49
50All "Row objects" derived from a Schema-attached L<DBIx::Class::ResultSet>
78f7b20c 51object (such as a typical C<< L<search|DBIx::Class::ResultSet/search>->
52L<next|DBIx::Class::ResultSet/next> >> call) are actually Result
93711422 53instances, based on your application's
5529838f 54L<Result Class|DBIx::Class::Manual::Glossary/Result Class>.
93711422 55
56L<DBIx::Class::Row> implements most of the row-based communication with the
57underlying storage, but a Result class B<should not inherit from it directly>.
58Usually, Result classes inherit from L<DBIx::Class::Core>, which in turn
59combines the methods from several classes, one of them being
60L<DBIx::Class::Row>. Therefore, while many of the methods available to a
61L<DBIx::Class::Core>-derived Result class are described in the following
62documentation, it does not detail all of the methods available to Result
fb13a49f 63objects. Refer to L<DBIx::Class::Manual::ResultClass> for more info.
a2531bf2 64
7624b19f 65=head1 METHODS
66
8091aa91 67=head2 new
7624b19f 68
47d7b769 69 my $result = My::Class->new(\%attrs);
a2531bf2 70
47d7b769 71 my $result = $schema->resultset('MySource')->new(\%colsandvalues);
a2531bf2 72
73=over
74
75=item Arguments: \%attrs or \%colsandvalues
76
fb13a49f 77=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
7624b19f 78
a2531bf2 79=back
80
fb13a49f 81While you can create a new result object by calling C<new> directly on
a2531bf2 82this class, you are better off calling it on a
83L<DBIx::Class::ResultSet> object.
84
85When calling it directly, you will not get a complete, usable row
50261284 86object until you pass or set the C<result_source> attribute, to a
a2531bf2 87L<DBIx::Class::ResultSource> instance that is attached to a
88L<DBIx::Class::Schema> with a valid connection.
89
90C<$attrs> is a hashref of column name, value data. It can also contain
50261284 91some other attributes such as the C<result_source>.
7624b19f 92
33dd4e80 93Passing an object, or an arrayref of objects as a value will call
94L<DBIx::Class::Relationship::Base/set_from_related> for you. When
95passed a hashref or an arrayref of hashrefs as the value, these will
96be turned into objects via new_related, and treated as if you had
97passed objects.
98
264f1571 99For a more involved explanation, see L<DBIx::Class::ResultSet/create>.
100
dc5f0ad3 101Please note that if a value is not passed to new, no value will be sent
102in the SQL INSERT call, and the column will therefore assume whatever
103default value was specified in your database. While DBIC will retrieve the
104value of autoincrement columns, it will never make an explicit database
105trip to retrieve default values assigned by the RDBMS. You can explicitly
106request that all values be fetched back from the database by calling
107L</discard_changes>, or you can supply an explicit C<undef> to columns
108with NULL as the default, and save yourself a SELECT.
109
110 CAVEAT:
111
112 The behavior described above will backfire if you use a foreign key column
113 with a database-defined default. If you call the relationship accessor on
114 an object that doesn't have a set value for the FK column, DBIC will throw
115 an exception, as it has no way of knowing the PK of the related object (if
116 there is one).
117
7624b19f 118=cut
119
33dd4e80 120## 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().
4a0eed52 121## This only works because DBIC doesn't yet care to check whether the new_related objects have been passed all their mandatory columns
33dd4e80 122## When doing the later insert, we need to make sure the PKs are set.
123## using _relationship_data in new and funky ways..
124## check Relationship::CascadeActions and Relationship::Accessor for compat
125## tests!
126
370f2ba2 127sub __new_related_find_or_new_helper {
a5f5e470 128 my ($self, $rel_name, $values) = @_;
68888c09 129
b7ded743 130 my $rsrc = $self->result_source;
131
68888c09 132 # create a mock-object so all new/set_column component overrides will run:
a5f5e470 133 my $rel_rs = $rsrc->related_source($rel_name)->resultset;
72c2540d 134 my $new_rel_obj = $rel_rs->new_result($values);
68888c09 135 my $proc_data = { $new_rel_obj->get_columns };
136
a5f5e470 137 if ($self->__their_pk_needs_us($rel_name)) {
138 MULTICREATE_DEBUG and print STDERR "MC $self constructing $rel_name via new_result\n";
68888c09 139 return $new_rel_obj;
370f2ba2 140 }
a5f5e470 141 elsif ($rsrc->_pk_depends_on($rel_name, $proc_data )) {
68888c09 142 if (! keys %$proc_data) {
143 # there is nothing to search for - blind create
a5f5e470 144 MULTICREATE_DEBUG and print STDERR "MC $self constructing default-insert $rel_name\n";
68888c09 145 }
146 else {
a5f5e470 147 MULTICREATE_DEBUG and print STDERR "MC $self constructing $rel_name via find_or_new\n";
68888c09 148 # this is not *really* find or new, as we don't want to double-new the
149 # data (thus potentially double encoding or whatever)
150 my $exists = $rel_rs->find ($proc_data);
151 return $exists if $exists;
152 }
153 return $new_rel_obj;
370f2ba2 154 }
68888c09 155 else {
b7ded743 156 my $us = $rsrc->source_name;
854929cb 157 $self->throw_exception (
a5f5e470 158 "Unable to determine relationship '$rel_name' direction from '$us', "
159 . "possibly due to a missing reverse-relationship on '$rel_name' to '$us'."
854929cb 160 );
370f2ba2 161 }
370f2ba2 162}
163
164sub __their_pk_needs_us { # this should maybe be in resultsource.
a5f5e470 165 my ($self, $rel_name) = @_;
72c2540d 166 my $rsrc = $self->result_source;
a5f5e470 167 my $reverse = $rsrc->reverse_relationship_info($rel_name);
168 my $rel_source = $rsrc->related_source($rel_name);
370f2ba2 169 my $us = { $self->get_columns };
170 foreach my $key (keys %$reverse) {
171 # if their primary key depends on us, then we have to
172 # just create a result and we'll fill it out afterwards
6d0ee587 173 return 1 if $rel_source->_pk_depends_on($key, $us);
370f2ba2 174 }
175 return 0;
176}
177
7624b19f 178sub new {
448f820f 179 my ($class, $attrs) = @_;
7624b19f 180 $class = ref $class if ref $class;
04786a4c 181
4c8ef945 182 my $new = bless { _column_data => {}, _in_storage => 0 }, $class;
09e1f723 183
7624b19f 184 if ($attrs) {
27f01d1f 185 $new->throw_exception("attrs must be a hashref")
186 unless ref($attrs) eq 'HASH';
b6d347e0 187
72c2540d 188 my $rsrc = delete $attrs->{-result_source};
4376a157 189 if ( my $h = delete $attrs->{-source_handle} ) {
72c2540d 190 $rsrc ||= $h->resolve;
4376a157 191 }
192
72c2540d 193 $new->result_source($rsrc) if $rsrc;
4376a157 194
195 if (my $col_from_rel = delete $attrs->{-cols_from_relations}) {
196 @{$new->{_ignore_at_insert}={}}{@$col_from_rel} = ();
197 }
198
61a622ee 199 my ($related,$inflated);
8222f722 200
61a622ee 201 foreach my $key (keys %$attrs) {
f8193780 202 if (ref $attrs->{$key} and ! is_literal_value($attrs->{$key}) ) {
af2d42c0 203 ## Can we extract this lot to use with update(_or .. ) ?
1a58752c 204 $new->throw_exception("Can't do multi-create without result source")
72c2540d 205 unless $rsrc;
206 my $info = $rsrc->relationship_info($key);
b82c8a28 207 my $acc_type = $info->{attrs}{accessor} || '';
208 if ($acc_type eq 'single') {
de7c7c53 209 my $rel_obj = delete $attrs->{$key};
6298a324 210 if(!blessed $rel_obj) {
370f2ba2 211 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
33dd4e80 212 }
2bc3c81e 213
e0cdf2cb 214 if ($rel_obj->in_storage) {
d4fe33d0 215 $new->{_rel_in_storage}{$key} = 1;
e0cdf2cb 216 $new->set_from_related($key, $rel_obj);
217 } else {
eed5492f 218 MULTICREATE_DEBUG and print STDERR "MC $new uninserted $key $rel_obj\n";
e0cdf2cb 219 }
2bc3c81e 220
de7c7c53 221 $related->{$key} = $rel_obj;
61a622ee 222 next;
b82c8a28 223 }
224 elsif ($acc_type eq 'multi' && ref $attrs->{$key} eq 'ARRAY' ) {
2ec8e594 225 my $others = delete $attrs->{$key};
e0cdf2cb 226 my $total = @$others;
227 my @objects;
228 foreach my $idx (0 .. $#$others) {
229 my $rel_obj = $others->[$idx];
6298a324 230 if(!blessed $rel_obj) {
370f2ba2 231 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
33dd4e80 232 }
2bc3c81e 233
e0cdf2cb 234 if ($rel_obj->in_storage) {
d4fe33d0 235 $rel_obj->throw_exception ('A multi relationship can not be pre-existing when doing multicreate. Something went wrong');
e0cdf2cb 236 } else {
e0cdf2cb 237 MULTICREATE_DEBUG and
eed5492f 238 print STDERR "MC $new uninserted $key $rel_obj (${\($idx+1)} of $total)\n";
e0cdf2cb 239 }
e0cdf2cb 240 push(@objects, $rel_obj);
2ec8e594 241 }
e0cdf2cb 242 $related->{$key} = \@objects;
2ec8e594 243 next;
b82c8a28 244 }
245 elsif ($acc_type eq 'filter') {
33dd4e80 246 ## 'filter' should disappear and get merged in with 'single' above!
2ec8e594 247 my $rel_obj = delete $attrs->{$key};
6298a324 248 if(!blessed $rel_obj) {
370f2ba2 249 $rel_obj = $new->__new_related_find_or_new_helper($key, $rel_obj);
33dd4e80 250 }
d4fe33d0 251 if ($rel_obj->in_storage) {
252 $new->{_rel_in_storage}{$key} = 1;
253 }
254 else {
eed5492f 255 MULTICREATE_DEBUG and print STDERR "MC $new uninserted $key $rel_obj\n";
e0cdf2cb 256 }
33dd4e80 257 $inflated->{$key} = $rel_obj;
61a622ee 258 next;
4006691d 259 }
260 elsif (
261 $rsrc->has_column($key)
262 and
263 $rsrc->column_info($key)->{_inflate_info}
264 ) {
61a622ee 265 $inflated->{$key} = $attrs->{$key};
266 next;
267 }
268 }
b6d347e0 269 $new->store_column($key => $attrs->{$key});
7624b19f 270 }
f90375dd 271
61a622ee 272 $new->{_relationship_data} = $related if $related;
273 $new->{_inflated_column} = $inflated if $inflated;
7624b19f 274 }
04786a4c 275
7624b19f 276 return $new;
277}
278
93711422 279=head2 $column_accessor
280
281 # Each pair does the same thing
282
283 # (un-inflated, regular column)
47d7b769 284 my $val = $result->get_column('first_name');
285 my $val = $result->first_name;
93711422 286
47d7b769 287 $result->set_column('first_name' => $val);
288 $result->first_name($val);
93711422 289
290 # (inflated column via DBIx::Class::InflateColumn::DateTime)
47d7b769 291 my $val = $result->get_inflated_column('last_modified');
292 my $val = $result->last_modified;
93711422 293
47d7b769 294 $result->set_inflated_column('last_modified' => $val);
295 $result->last_modified($val);
93711422 296
297=over
298
299=item Arguments: $value?
300
fb13a49f 301=item Return Value: $value
93711422 302
303=back
304
305A column accessor method is created for each column, which is used for
306getting/setting the value for that column.
307
8ed69929 308The actual method name is based on the
309L<accessor|DBIx::Class::ResultSource/accessor> name given during the
310L<Result Class|DBIx::Class::Manual::ResultClass> L<column definition
311|DBIx::Class::ResultSource/add_columns>. Like L</set_column>, this
312will not store the data in the database until L</insert> or L</update>
313is called on the row.
93711422 314
8091aa91 315=head2 insert
7624b19f 316
47d7b769 317 $result->insert;
a2531bf2 318
319=over
7624b19f 320
a2531bf2 321=item Arguments: none
322
fb13a49f 323=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 324
325=back
326
327Inserts an object previously created by L</new> into the database if
5298bbb5 328it isn't already in there. Returns the object itself. To insert an
329entirely new row into the database, use L<DBIx::Class::ResultSet/create>.
7624b19f 330
fb13a49f 331To fetch an uninserted result object, call
69bc5f2b 332L<new_result|DBIx::Class::ResultSet/new_result> on a resultset.
e91e756c 333
264f1571 334This will also insert any uninserted, related objects held inside this
335one, see L<DBIx::Class::ResultSet/create> for more details.
336
7624b19f 337=cut
338
339sub insert {
340 my ($self) = @_;
341 return $self if $self->in_storage;
72c2540d 342 my $rsrc = $self->result_source;
aeb1bf75 343 $self->throw_exception("No result_source set on this object; can't insert")
72c2540d 344 unless $rsrc;
6e399b4f 345
72c2540d 346 my $storage = $rsrc->storage;
a85b7ebe 347
9c6d6d93 348 my $rollback_guard;
349
33dd4e80 350 # Check if we stored uninserted relobjs here in new()
b6d347e0 351 my %related_stuff = (%{$self->{_relationship_data} || {}},
33dd4e80 352 %{$self->{_inflated_column} || {}});
9c6d6d93 353
d4fe33d0 354 # insert what needs to be inserted before us
355 my %pre_insert;
a5f5e470 356 for my $rel_name (keys %related_stuff) {
357 my $rel_obj = $related_stuff{$rel_name};
9c6d6d93 358
a5f5e470 359 if (! $self->{_rel_in_storage}{$rel_name}) {
6298a324 360 next unless (blessed $rel_obj && $rel_obj->isa('DBIx::Class::Row'));
a8c98174 361
72c2540d 362 next unless $rsrc->_pk_depends_on(
a5f5e470 363 $rel_name, { $rel_obj->get_columns }
d4fe33d0 364 );
a8c98174 365
d4fe33d0 366 # The guard will save us if we blow out of this scope via die
a85b7ebe 367 $rollback_guard ||= $storage->txn_scope_guard;
9c6d6d93 368
a5f5e470 369 MULTICREATE_DEBUG and print STDERR "MC $self pre-reconstructing $rel_name $rel_obj\n";
e0cdf2cb 370
380d34f5 371 my $them = { %{$rel_obj->{_relationship_data} || {} }, $rel_obj->get_columns };
68888c09 372 my $existing;
373
374 # if there are no keys - nothing to search for
5567c8f8 375 if (keys %$them and $existing = $rsrc->related_source($rel_name)
68888c09 376 ->resultset
377 ->find($them)
378 ) {
379 %{$rel_obj} = %{$existing};
380 }
381 else {
382 $rel_obj->insert;
383 }
d4fe33d0 384
a5f5e470 385 $self->{_rel_in_storage}{$rel_name} = 1;
33dd4e80 386 }
d4fe33d0 387
a5f5e470 388 $self->set_from_related($rel_name, $rel_obj);
389 delete $related_stuff{$rel_name};
d4fe33d0 390 }
391
392 # start a transaction here if not started yet and there is more stuff
393 # to insert after us
394 if (keys %related_stuff) {
a85b7ebe 395 $rollback_guard ||= $storage->txn_scope_guard
33dd4e80 396 }
6e399b4f 397
09e1f723 398 MULTICREATE_DEBUG and do {
399 no warnings 'uninitialized';
eed5492f 400 print STDERR "MC $self inserting (".join(', ', $self->get_columns).")\n";
09e1f723 401 };
ac8e89d7 402
8b9473f5 403 # perform the insert - the storage will return everything it is asked to
404 # (autoinc primary columns and any retrieve_on_insert columns)
a85b7ebe 405 my %current_rowdata = $self->get_columns;
a85b7ebe 406 my $returned_cols = $storage->insert(
72c2540d 407 $rsrc,
8b9473f5 408 { %current_rowdata }, # what to insert, copy because the storage *will* change it
1e45aa87 409 );
410
a85b7ebe 411 for (keys %$returned_cols) {
8b9473f5 412 $self->store_column($_, $returned_cols->{$_})
413 # this ensures we fire store_column only once
414 # (some asshats like overriding it)
415 if (
cf6692ad 416 (!exists $current_rowdata{$_})
8b9473f5 417 or
cf6692ad 418 (defined $current_rowdata{$_} xor defined $returned_cols->{$_})
419 or
420 (defined $current_rowdata{$_} and $current_rowdata{$_} ne $returned_cols->{$_})
8b9473f5 421 );
ac8e89d7 422 }
33dd4e80 423
5ef76b8b 424 delete $self->{_column_data_in_storage};
425 $self->in_storage(1);
e0cdf2cb 426
370f2ba2 427 $self->{_dirty_columns} = {};
428 $self->{related_resultsets} = {};
429
a5f5e470 430 foreach my $rel_name (keys %related_stuff) {
431 next unless $rsrc->has_relationship ($rel_name);
31c3800e 432
a5f5e470 433 my @cands = ref $related_stuff{$rel_name} eq 'ARRAY'
434 ? @{$related_stuff{$rel_name}}
435 : $related_stuff{$rel_name}
31c3800e 436 ;
d4fe33d0 437
6298a324 438 if (@cands && blessed $cands[0] && $cands[0]->isa('DBIx::Class::Row')
31c3800e 439 ) {
a5f5e470 440 my $reverse = $rsrc->reverse_relationship_info($rel_name);
d4fe33d0 441 foreach my $obj (@cands) {
442 $obj->set_from_related($_, $self) for keys %$reverse;
a5f5e470 443 if ($self->__their_pk_needs_us($rel_name)) {
444 if (exists $self->{_ignore_at_insert}{$rel_name}) {
445 MULTICREATE_DEBUG and print STDERR "MC $self skipping post-insert on $rel_name\n";
65ee2b31 446 }
447 else {
a5f5e470 448 MULTICREATE_DEBUG and print STDERR "MC $self inserting $rel_name $obj\n";
65ee2b31 449 $obj->insert;
370f2ba2 450 }
d4fe33d0 451 } else {
eed5492f 452 MULTICREATE_DEBUG and print STDERR "MC $self post-inserting $obj\n";
d4fe33d0 453 $obj->insert();
8222f722 454 }
33dd4e80 455 }
456 }
457 }
33dd4e80 458
d4fe33d0 459 delete $self->{_ignore_at_insert};
5ef76b8b 460
d4fe33d0 461 $rollback_guard->commit if $rollback_guard;
462
7624b19f 463 return $self;
464}
465
8091aa91 466=head2 in_storage
7624b19f 467
47d7b769 468 $result->in_storage; # Get value
469 $result->in_storage(1); # Set value
a2531bf2 470
471=over
472
473=item Arguments: none or 1|0
474
fb13a49f 475=item Return Value: 1|0
a2531bf2 476
477=back
7624b19f 478
e91e756c 479Indicates whether the object exists as a row in the database or
480not. This is set to true when L<DBIx::Class::ResultSet/find>,
5529838f 481L<DBIx::Class::ResultSet/create> or L<DBIx::Class::Row/insert>
482are invoked.
e91e756c 483
69bc5f2b 484Creating a result object using L<DBIx::Class::ResultSet/new_result>, or
485calling L</delete> on one, sets it to false.
7624b19f 486
7624b19f 487
8091aa91 488=head2 update
7624b19f 489
47d7b769 490 $result->update(\%columns?)
a2531bf2 491
492=over
7624b19f 493
a2531bf2 494=item Arguments: none or a hashref
7624b19f 495
fb13a49f 496=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 497
498=back
499
fb13a49f 500Throws an exception if the result object is not yet in the database,
47d7b769 501according to L</in_storage>. Returns the object itself.
a2531bf2 502
503This method issues an SQL UPDATE query to commit any changes to the
d6988be8 504object to the database if required (see L</get_dirty_columns>).
505It throws an exception if a proper WHERE clause uniquely identifying
506the database row can not be constructed (see
507L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
508for more details).
a2531bf2 509
0d0fcdbf 510Also takes an optional hashref of C<< column_name => value >> pairs
a2531bf2 511to update on the object first. Be aware that the hashref will be
512passed to C<set_inflated_columns>, which might edit it in place, so
513don't rely on it being the same after a call to C<update>. If you
514need to preserve the hashref, it is sufficient to pass a shallow copy
515to C<update>, e.g. ( { %{ $href } } )
d5d833d9 516
05d1bc9c 517If the values passed or any of the column values set on the object
48580715 518contain scalar references, e.g.:
05d1bc9c 519
47d7b769 520 $result->last_modified(\'NOW()')->update();
05d1bc9c 521 # OR
47d7b769 522 $result->update({ last_modified => \'NOW()' });
05d1bc9c 523
524The update will pass the values verbatim into SQL. (See
fb13a49f 525L<SQL::Abstract> docs). The values in your Result object will NOT change
05d1bc9c 526as a result of the update call, if you want the object to be updated
527with the actual values from the database, call L</discard_changes>
528after the update.
529
47d7b769 530 $result->update()->discard_changes();
a2531bf2 531
532To determine before calling this method, which column values have
533changed and will be updated, call L</get_dirty_columns>.
534
535To check if any columns will be updated, call L</is_changed>.
536
537To force a column to be updated, call L</make_column_dirty> before
538this method.
05d1bc9c 539
7624b19f 540=cut
541
542sub update {
543 my ($self, $upd) = @_;
6e399b4f 544
bacf6f12 545 $self->set_inflated_columns($upd) if $upd;
de5ce481 546
014789be 547 my %to_update = $self->get_dirty_columns
548 or return $self;
549
de5ce481 550 $self->throw_exception( "Not in database" ) unless $self->in_storage;
551
88cb6a1d 552 my $rows = $self->result_source->storage->update(
867f1b28 553 $self->result_source, \%to_update, $self->_storage_ident_condition
cf856357 554 );
7624b19f 555 if ($rows == 0) {
701da8c4 556 $self->throw_exception( "Can't update ${self}: row not found" );
7624b19f 557 } elsif ($rows > 1) {
701da8c4 558 $self->throw_exception("Can't update ${self}: updated more than one row");
7624b19f 559 }
560 $self->{_dirty_columns} = {};
64acc2bc 561 $self->{related_resultsets} = {};
5ef76b8b 562 delete $self->{_column_data_in_storage};
7624b19f 563 return $self;
564}
565
8091aa91 566=head2 delete
7624b19f 567
47d7b769 568 $result->delete
a2531bf2 569
570=over
571
572=item Arguments: none
7624b19f 573
fb13a49f 574=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 575
576=back
577
578Throws an exception if the object is not in the database according to
d6988be8 579L</in_storage>. Also throws an exception if a proper WHERE clause
580uniquely identifying the database row can not be constructed (see
581L<significance of primary keys|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
582for more details).
a2531bf2 583
584The object is still perfectly usable, but L</in_storage> will
ea36f4e4 585now return 0 and the object must be reinserted using L</insert>
b6d347e0 586before it can be used to L</update> the row again.
a2531bf2 587
588If you delete an object in a class with a C<has_many> relationship, an
589attempt is made to delete all the related objects as well. To turn
590this behaviour off, pass C<< cascade_delete => 0 >> in the C<$attr>
591hashref of the relationship, see L<DBIx::Class::Relationship>. Any
592database-level cascade or restrict will take precedence over a
281e677e 593DBIx-Class-based cascading delete, since DBIx-Class B<deletes the
594main row first> and only then attempts to delete any remaining related
595rows.
a2531bf2 596
b1d16ffd 597If you delete an object within a txn_do() (see L<DBIx::Class::Storage/txn_do>)
fb13a49f 598and the transaction subsequently fails, the result object will remain marked as
b1d16ffd 599not being in storage. If you know for a fact that the object is still in
600storage (i.e. by inspecting the cause of the transaction's failure), you can
601use C<< $obj->in_storage(1) >> to restore consistency between the object and
602the database. This would allow a subsequent C<< $obj->delete >> to work
603as expected.
604
a2531bf2 605See also L<DBIx::Class::ResultSet/delete>.
7624b19f 606
607=cut
608
609sub delete {
610 my $self = shift;
611 if (ref $self) {
701da8c4 612 $self->throw_exception( "Not in database" ) unless $self->in_storage;
cf856357 613
88cb6a1d 614 $self->result_source->storage->delete(
867f1b28 615 $self->result_source, $self->_storage_ident_condition
cf856357 616 );
617
5ef76b8b 618 delete $self->{_column_data_in_storage};
4c8ef945 619 $self->in_storage(0);
cf856357 620 }
621 else {
ddcc02d1 622 my $rsrc = dbic_internal_try { $self->result_source_instance }
5298bbb5 623 or $self->throw_exception("Can't do class delete without a ResultSource instance");
624
aeb1bf75 625 my $attrs = @_ > 1 && ref $_[$#_] eq 'HASH' ? { %{pop(@_)} } : {};
626 my $query = ref $_[0] eq 'HASH' ? $_[0] : {@_};
5298bbb5 627 $rsrc->resultset->search(@_)->delete;
7624b19f 628 }
629 return $self;
630}
631
8091aa91 632=head2 get_column
7624b19f 633
47d7b769 634 my $val = $result->get_column($col);
a2531bf2 635
636=over
637
638=item Arguments: $columnname
639
fb13a49f 640=item Return Value: The value of the column
a2531bf2 641
642=back
643
644Throws an exception if the column name given doesn't exist according
16667b3a 645to L<has_column|DBIx::Class::ResultSource/has_column>.
7624b19f 646
fb13a49f 647Returns a raw column value from the result object, if it has already
e91e756c 648been fetched from the database or set by an accessor.
649
650If an L<inflated value|DBIx::Class::InflateColumn> has been set, it
651will be deflated and returned.
7624b19f 652
ea36f4e4 653Note that if you used the C<columns> or the C<select/as>
654L<search attributes|DBIx::Class::ResultSet/ATTRIBUTES> on the resultset from
47d7b769 655which C<$result> was derived, and B<did not include> C<$columnname> in the list,
ea36f4e4 656this method will return C<undef> even if the database contains some value.
657
a2531bf2 658To retrieve all loaded column values as a hash, use L</get_columns>.
659
7624b19f 660=cut
661
662sub get_column {
663 my ($self, $column) = @_;
701da8c4 664 $self->throw_exception( "Can't fetch data as class method" ) unless ref $self;
5ae153d7 665
666 return $self->{_column_data}{$column}
667 if exists $self->{_column_data}{$column};
668
61a622ee 669 if (exists $self->{_inflated_column}{$column}) {
5ae153d7 670 # deflate+return cycle
671 return $self->store_column($column, $self->_deflated_column(
672 $column, $self->{_inflated_column}{$column}
673 ));
61a622ee 674 }
5ae153d7 675
75ef16a7 676 $self->throw_exception( "No such column '${column}' on " . ref $self )
4006691d 677 unless $self->result_source->has_column($column);
5ae153d7 678
7624b19f 679 return undef;
680}
681
9b83fccd 682=head2 has_column_loaded
683
47d7b769 684 if ( $result->has_column_loaded($col) ) {
9b83fccd 685 print "$col has been loaded from db";
686 }
687
a2531bf2 688=over
689
690=item Arguments: $columnname
691
fb13a49f 692=item Return Value: 0|1
a2531bf2 693
694=back
695
9b83fccd 696Returns a true value if the column value has been loaded from the
697database (or set locally).
698
699=cut
700
def81720 701sub has_column_loaded {
702 my ($self, $column) = @_;
703 $self->throw_exception( "Can't call has_column data as class method" ) unless ref $self;
5ae153d7 704
705 return (
706 exists $self->{_inflated_column}{$column}
707 or
708 exists $self->{_column_data}{$column}
709 ) ? 1 : 0;
def81720 710}
711
8091aa91 712=head2 get_columns
076a6864 713
47d7b769 714 my %data = $result->get_columns;
a2531bf2 715
716=over
717
718=item Arguments: none
076a6864 719
fb13a49f 720=item Return Value: A hash of columnname, value pairs.
a2531bf2 721
722=back
723
724Returns all loaded column data as a hash, containing raw values. To
725get just one value for a particular column, use L</get_column>.
076a6864 726
c0a171bf 727See L</get_inflated_columns> to get the inflated values.
728
076a6864 729=cut
730
731sub get_columns {
732 my $self = shift;
61a622ee 733 if (exists $self->{_inflated_column}) {
5ae153d7 734 # deflate cycle for each inflation, including filter rels
61a622ee 735 foreach my $col (keys %{$self->{_inflated_column}}) {
6dd43920 736 unless (exists $self->{_column_data}{$col}) {
737
738 # if cached related_resultset is present assume this was a prefetch
739 carp_unique(
740 "Returning primary keys of prefetched 'filter' rels as part of get_columns() is deprecated and will "
741 . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
742 ) if (
743 ! $ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}
744 and
745 defined $self->{related_resultsets}{$col}
746 and
747 defined $self->{related_resultsets}{$col}->get_cache
748 );
749
750 $self->store_column($col, $self->_deflated_column($col, $self->{_inflated_column}{$col}));
751 }
61a622ee 752 }
753 }
cb5f2eea 754 return %{$self->{_column_data}};
d7156e50 755}
756
757=head2 get_dirty_columns
758
47d7b769 759 my %data = $result->get_dirty_columns;
a2531bf2 760
761=over
762
763=item Arguments: none
d7156e50 764
fb13a49f 765=item Return Value: A hash of column, value pairs
a2531bf2 766
767=back
768
769Only returns the column, value pairs for those columns that have been
770changed on this object since the last L</update> or L</insert> call.
771
772See L</get_columns> to fetch all column/value pairs.
d7156e50 773
774=cut
775
776sub get_dirty_columns {
777 my $self = shift;
778 return map { $_ => $self->{_column_data}{$_} }
779 keys %{$self->{_dirty_columns}};
076a6864 780}
781
6dbea98e 782=head2 make_column_dirty
783
47d7b769 784 $result->make_column_dirty($col)
a2531bf2 785
786=over
787
788=item Arguments: $columnname
789
fb13a49f 790=item Return Value: not defined
a2531bf2 791
792=back
793
794Throws an exception if the column does not exist.
795
796Marks a column as having been changed regardless of whether it has
b6d347e0 797really changed.
6dbea98e 798
799=cut
4c8ef945 800
6dbea98e 801sub make_column_dirty {
802 my ($self, $column) = @_;
803
75ef16a7 804 $self->throw_exception( "No such column '${column}' on " . ref $self )
4006691d 805 unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
497d874a 806
b6d347e0 807 # the entire clean/dirty code relies on exists, not on true/false
497d874a 808 return 1 if exists $self->{_dirty_columns}{$column};
809
6dbea98e 810 $self->{_dirty_columns}{$column} = 1;
497d874a 811
812 # if we are just now making the column dirty, and if there is an inflated
813 # value, force it over the deflated one
814 if (exists $self->{_inflated_column}{$column}) {
815 $self->store_column($column,
816 $self->_deflated_column(
817 $column, $self->{_inflated_column}{$column}
818 )
819 );
820 }
6dbea98e 821}
822
ba4a6453 823=head2 get_inflated_columns
824
e91e756c 825 my %inflated_data = $obj->get_inflated_columns;
ba4a6453 826
a2531bf2 827=over
828
829=item Arguments: none
830
fb13a49f 831=item Return Value: A hash of column, object|value pairs
a2531bf2 832
833=back
834
835Returns a hash of all column keys and associated values. Values for any
836columns set to use inflation will be inflated and returns as objects.
837
838See L</get_columns> to get the uninflated values.
839
840See L<DBIx::Class::InflateColumn> for how to setup inflation.
ba4a6453 841
842=cut
843
844sub get_inflated_columns {
845 my $self = shift;
d61b2132 846
4006691d 847 my $loaded_colinfo = $self->result_source->columns_info;
848 $self->has_column_loaded($_) or delete $loaded_colinfo->{$_}
849 for keys %$loaded_colinfo;
d61b2132 850
6dd43920 851 my %cols_to_return = ( %{$self->{_column_data}}, %$loaded_colinfo );
852
853 unless ($ENV{DBIC_COLUMNS_INCLUDE_FILTER_RELS}) {
854 for (keys %$loaded_colinfo) {
855 # if cached related_resultset is present assume this was a prefetch
856 if (
857 $loaded_colinfo->{$_}{_inflate_info}
858 and
859 defined $self->{related_resultsets}{$_}
860 and
861 defined $self->{related_resultsets}{$_}->get_cache
862 ) {
863 carp_unique(
864 "Returning prefetched 'filter' rels as part of get_inflated_columns() is deprecated and will "
865 . 'eventually be removed entirely (set DBIC_COLUMNS_INCLUDE_FILTER_RELS to disable this warning)'
866 );
867 last;
868 }
d61b2132 869 }
870 }
871
6dd43920 872 map { $_ => (
873 (
874 ! exists $loaded_colinfo->{$_}
875 or
876 (
877 exists $loaded_colinfo->{$_}{accessor}
878 and
879 ! defined $loaded_colinfo->{$_}{accessor}
880 )
881 ) ? $self->get_column($_)
882 : $self->${ \(
883 defined $loaded_colinfo->{$_}{accessor}
884 ? $loaded_colinfo->{$_}{accessor}
885 : $_
886 )}
887 )} keys %cols_to_return;
ba4a6453 888}
889
ca8a1270 890sub _is_column_numeric {
57e9c142 891 my ($self, $column) = @_;
892
5567c8f8 893 my $rsrc;
57e9c142 894
5567c8f8 895 return undef
896 unless ( $rsrc = $self->result_source )->has_column($column);
897
898 my $colinfo = $rsrc->column_info ($column);
0bb1a52f 899
900 # cache for speed (the object may *not* have a resultsource instance)
50261284 901 if (
902 ! defined $colinfo->{is_numeric}
903 and
5567c8f8 904 my $storage = dbic_internal_try { $rsrc->schema->storage }
50261284 905 ) {
0bb1a52f 906 $colinfo->{is_numeric} =
50261284 907 $storage->is_datatype_numeric ($colinfo->{data_type})
0bb1a52f 908 ? 1
909 : 0
910 ;
911 }
912
913 return $colinfo->{is_numeric};
914}
915
8091aa91 916=head2 set_column
7624b19f 917
47d7b769 918 $result->set_column($col => $val);
a2531bf2 919
920=over
921
922=item Arguments: $columnname, $value
923
fb13a49f 924=item Return Value: $value
a2531bf2 925
926=back
7624b19f 927
e91e756c 928Sets a raw column value. If the new value is different from the old one,
a2531bf2 929the column is marked as dirty for when you next call L</update>.
7624b19f 930
ea36f4e4 931If passed an object or reference as a value, this method will happily
932attempt to store it, and a later L</insert> or L</update> will try and
a2531bf2 933stringify/numify as appropriate. To set an object to be deflated
93711422 934instead, see L</set_inflated_columns>, or better yet, use L</$column_accessor>.
e91e756c 935
7624b19f 936=cut
937
938sub set_column {
1d0057bd 939 my ($self, $column, $new_value) = @_;
940
5ef76b8b 941 my $had_value = $self->has_column_loaded($column);
5ae153d7 942 my $old_value = $self->get_column($column);
1d0057bd 943
b236052f 944 $new_value = $self->store_column($column, $new_value);
8f9eff75 945
cde96798 946 my $dirty =
947 $self->{_dirty_columns}{$column}
948 ||
57e9c142 949 ( $self->in_storage # no point tracking dirtyness on uninserted data
cde96798 950 ? ! $self->_eq_column_values ($column, $old_value, $new_value)
951 : 1
57e9c142 952 )
cde96798 953 ;
8f9eff75 954
35f5c265 955 if ($dirty) {
956 # FIXME sadly the update code just checks for keys, not for their value
957 $self->{_dirty_columns}{$column} = 1;
958
959 # Clear out the relation/inflation cache related to this column
960 #
961 # FIXME - this is a quick *largely incorrect* hack, pending a more
962 # serious rework during the merge of single and filter rels
a5f5e470 963 my $rel_names = $self->result_source->{_relationships};
964 for my $rel_name (keys %$rel_names) {
35f5c265 965
a5f5e470 966 my $acc = $rel_names->{$rel_name}{attrs}{accessor} || '';
35f5c265 967
a5f5e470 968 if ( $acc eq 'single' and $rel_names->{$rel_name}{attrs}{fk_columns}{$column} ) {
969 delete $self->{related_resultsets}{$rel_name};
970 delete $self->{_relationship_data}{$rel_name};
971 #delete $self->{_inflated_column}{$rel_name};
35f5c265 972 }
a5f5e470 973 elsif ( $acc eq 'filter' and $rel_name eq $column) {
974 delete $self->{related_resultsets}{$rel_name};
975 #delete $self->{_relationship_data}{$rel_name};
976 delete $self->{_inflated_column}{$rel_name};
35f5c265 977 }
8f9eff75 978 }
5ef76b8b 979
980 if (
981 # value change from something (even if NULL)
982 $had_value
983 and
984 # no storage - no storage-value
5ae153d7 985 $self->in_storage
5ef76b8b 986 and
987 # no value already stored (multiple changes before commit to storage)
988 ! exists $self->{_column_data_in_storage}{$column}
989 and
990 $self->_track_storage_value($column)
991 ) {
992 $self->{_column_data_in_storage}{$column} = $old_value;
8f9eff75 993 }
994 }
995
1d0057bd 996 return $new_value;
7624b19f 997}
e60dc79f 998
cde96798 999sub _eq_column_values {
1000 my ($self, $col, $old, $new) = @_;
e60dc79f 1001
cde96798 1002 if (defined $old xor defined $new) {
1003 return 0;
1004 }
1005 elsif (not defined $old) { # both undef
1006 return 1;
1007 }
3705e3b2 1008 elsif (
1009 is_literal_value $old
1010 or
1011 is_literal_value $new
1012 ) {
1013 return 0;
1014 }
cde96798 1015 elsif ($old eq $new) {
1016 return 1;
1017 }
1018 elsif ($self->_is_column_numeric($col)) { # do a numeric comparison if datatype allows it
1019 return $old == $new;
1020 }
1021 else {
1022 return 0;
1023 }
1024}
1025
5ef76b8b 1026# returns a boolean indicating if the passed column should have its original
1027# value tracked between column changes and commitment to storage
1028sub _track_storage_value {
1029 my ($self, $col) = @_;
87b12551 1030 return scalar grep
1031 { $col eq $_ }
1032 $self->result_source->primary_columns
1033 ;
7624b19f 1034}
1035
8091aa91 1036=head2 set_columns
076a6864 1037
47d7b769 1038 $result->set_columns({ $col => $val, ... });
a2531bf2 1039
b6d347e0 1040=over
076a6864 1041
a2531bf2 1042=item Arguments: \%columndata
1043
fb13a49f 1044=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 1045
1046=back
1047
1048Sets multiple column, raw value pairs at once.
1049
1050Works as L</set_column>.
076a6864 1051
1052=cut
1053
1054sub set_columns {
72c2540d 1055 my ($self, $values) = @_;
1056 $self->set_column( $_, $values->{$_} ) for keys %$values;
c01ab172 1057 return $self;
076a6864 1058}
1059
bacf6f12 1060=head2 set_inflated_columns
1061
a5f5e470 1062 $result->set_inflated_columns({ $col => $val, $rel_name => $obj, ... });
a2531bf2 1063
1064=over
1065
1066=item Arguments: \%columndata
1067
fb13a49f 1068=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 1069
1070=back
1071
1072Sets more than one column value at once. Any inflated values are
b6d347e0 1073deflated and the raw values stored.
bacf6f12 1074
fb13a49f 1075Any related values passed as Result objects, using the relation name as a
a2531bf2 1076key, are reduced to the appropriate foreign key values and stored. If
fb13a49f 1077instead of related result objects, a hashref of column, value data is
a2531bf2 1078passed, will create the related object first then store.
1079
1080Will even accept arrayrefs of data as a value to a
1081L<DBIx::Class::Relationship/has_many> key, and create the related
1082objects if necessary.
1083
c1300297 1084Be aware that the input hashref might be edited in place, so don't rely
a2531bf2 1085on it being the same after a call to C<set_inflated_columns>. If you
1086need to preserve the hashref, it is sufficient to pass a shallow copy
1087to C<set_inflated_columns>, e.g. ( { %{ $href } } )
1088
1089See also L<DBIx::Class::Relationship::Base/set_from_related>.
bacf6f12 1090
1091=cut
1092
1093sub set_inflated_columns {
1094 my ( $self, $upd ) = @_;
4006691d 1095 my $rsrc;
bacf6f12 1096 foreach my $key (keys %$upd) {
1097 if (ref $upd->{$key}) {
4006691d 1098 $rsrc ||= $self->result_source;
1099 my $info = $rsrc->relationship_info($key);
b82c8a28 1100 my $acc_type = $info->{attrs}{accessor} || '';
5ae153d7 1101
b82c8a28 1102 if ($acc_type eq 'single') {
72c2540d 1103 my $rel_obj = delete $upd->{$key};
1104 $self->set_from_related($key => $rel_obj);
1105 $self->{_relationship_data}{$key} = $rel_obj;
bacf6f12 1106 }
b82c8a28 1107 elsif ($acc_type eq 'multi') {
1108 $self->throw_exception(
1109 "Recursive update is not supported over relationships of type '$acc_type' ($key)"
1110 );
1111 }
4006691d 1112 elsif (
1113 $rsrc->has_column($key)
1114 and
1115 exists $rsrc->column_info($key)->{_inflate_info}
1116 ) {
a7be8807 1117 $self->set_inflated_column($key, delete $upd->{$key});
bacf6f12 1118 }
1119 }
1120 }
b6d347e0 1121 $self->set_columns($upd);
bacf6f12 1122}
1123
8091aa91 1124=head2 copy
076a6864 1125
1126 my $copy = $orig->copy({ change => $to, ... });
1127
a2531bf2 1128=over
1129
1130=item Arguments: \%replacementdata
1131
fb13a49f 1132=item Return Value: L<$result|DBIx::Class::Manual::ResultClass> copy
a2531bf2 1133
1134=back
1135
1136Inserts a new row into the database, as a copy of the original
1137object. If a hashref of replacement data is supplied, these will take
ce0893e0 1138precedence over data in the original. Also any columns which have
1139the L<column info attribute|DBIx::Class::ResultSource/add_columns>
1140C<< is_auto_increment => 1 >> are explicitly removed before the copy,
1141so that the database can insert its own autoincremented values into
1142the new object.
a2531bf2 1143
f928c965 1144Relationships will be followed by the copy procedure B<only> if the
48580715 1145relationship specifies a true value for its
f928c965 1146L<cascade_copy|DBIx::Class::Relationship::Base> attribute. C<cascade_copy>
1147is set by default on C<has_many> relationships and unset on all others.
076a6864 1148
1149=cut
1150
c01ab172 1151sub copy {
1152 my ($self, $changes) = @_;
333cce60 1153 $changes ||= {};
cc506f8b 1154 my $col_data = { $self->get_columns };
52416317 1155
4006691d 1156 my $rsrc = $self->result_source;
1157
cc506f8b 1158 my $colinfo = $rsrc->columns_info;
fde6e28e 1159 foreach my $col (keys %$col_data) {
1160 delete $col_data->{$col}
cc506f8b 1161 if ( ! $colinfo->{$col} or $colinfo->{$col}{is_auto_increment} );
fde6e28e 1162 }
04786a4c 1163
1164 my $new = { _column_data => $col_data };
1165 bless $new, ref $self;
1166
4006691d 1167 $new->result_source($rsrc);
bacf6f12 1168 $new->set_inflated_columns($changes);
333cce60 1169 $new->insert;
35688220 1170
b6d347e0 1171 # Its possible we'll have 2 relations to the same Source. We need to make
48580715 1172 # sure we don't try to insert the same row twice else we'll violate unique
35688220 1173 # constraints
a5f5e470 1174 my $rel_names_copied = {};
35688220 1175
4006691d 1176 foreach my $rel_name ($rsrc->relationships) {
1177 my $rel_info = $rsrc->relationship_info($rel_name);
35688220 1178
1179 next unless $rel_info->{attrs}{cascade_copy};
b6d347e0 1180
a4e58b18 1181 my $foreign_vals;
a5f5e470 1182 my $copied = $rel_names_copied->{ $rel_info->{source} } ||= {};
b6d347e0 1183
a4e58b18 1184 $copied->{$_->ID}++ or $_->copy(
1185
1186 $foreign_vals ||= $rsrc->_resolve_relationship_condition(
1187 infer_values_based_on => {},
1188 rel_name => $rel_name,
1189 self_result_object => $new,
1190
1191 self_alias => "\xFE", # irrelevant
1192 foreign_alias => "\xFF", # irrelevant,
1193 )->{inferred_values}
1194
1195 ) for $self->search_related($rel_name)->all;
333cce60 1196 }
2c4c67b6 1197 return $new;
c01ab172 1198}
1199
8091aa91 1200=head2 store_column
7624b19f 1201
47d7b769 1202 $result->store_column($col => $val);
7624b19f 1203
a2531bf2 1204=over
1205
1206=item Arguments: $columnname, $value
1207
fb13a49f 1208=item Return Value: The value sent to storage
a2531bf2 1209
1210=back
1211
1212Set a raw value for a column without marking it as changed. This
1213method is used internally by L</set_column> which you should probably
1214be using.
1215
fb13a49f 1216This is the lowest level at which data is set on a result object,
a2531bf2 1217extend this method to catch all data setting methods.
7624b19f 1218
1219=cut
1220
1221sub store_column {
1222 my ($self, $column, $value) = @_;
75ef16a7 1223 $self->throw_exception( "No such column '${column}' on " . ref $self )
4006691d 1224 unless exists $self->{_column_data}{$column} || $self->result_source->has_column($column);
75d07914 1225 $self->throw_exception( "set_column called for ${column} without value" )
7624b19f 1226 if @_ < 3;
f6d731aa 1227
a2c77c97 1228 return $self->{_column_data}{$column} = $value
1229 unless length ref $value and my $vref = is_plain_value( $value );
1230
1231 # if we are dealing with a value/ref - there are a couple possibilities
1232 # unpack the underlying piece of data and stringify all objects explicitly
1233 # ( to accomodate { -value => ... } and guard against overloaded objects
f6d731aa 1234 # with defined stringification AND fallback => 0 (ugh!)
a2c77c97 1235 $self->{_column_data}{$column} = defined blessed $$vref
1236 ? "$$vref"
1237 : $$vref
f6d731aa 1238 ;
7624b19f 1239}
1240
b52e9bf8 1241=head2 inflate_result
1242
c01ab172 1243 Class->inflate_result($result_source, \%me, \%prefetch?)
b52e9bf8 1244
a2531bf2 1245=over
1246
fb13a49f 1247=item Arguments: L<$result_source|DBIx::Class::ResultSource>, \%columndata, \%prefetcheddata
a2531bf2 1248
fb13a49f 1249=item Return Value: L<$result|DBIx::Class::Manual::ResultClass>
a2531bf2 1250
1251=back
1252
1253All L<DBIx::Class::ResultSet> methods that retrieve data from the
fb13a49f 1254database and turn it into result objects call this method.
a2531bf2 1255
1256Extend this method in your Result classes to hook into this process,
1257for example to rebless the result into a different class.
1258
1259Reblessing can also be done more easily by setting C<result_class> in
1260your Result class. See L<DBIx::Class::ResultSource/result_class>.
b52e9bf8 1261
db2b2eb6 1262Different types of results can also be created from a particular
1263L<DBIx::Class::ResultSet>, see L<DBIx::Class::ResultSet/result_class>.
1264
b52e9bf8 1265=cut
1266
1267sub inflate_result {
72c2540d 1268 my ($class, $rsrc, $me, $prefetch) = @_;
aec3eff1 1269
50261284 1270 my $new = bless
72c2540d 1271 { _column_data => $me, _result_source => $rsrc },
50261284 1272 ref $class || $class
1273 ;
04786a4c 1274
ce556881 1275 if ($prefetch) {
a5f5e470 1276 for my $rel_name ( keys %$prefetch ) {
35c77aa3 1277
a5f5e470 1278 my $relinfo = $rsrc->relationship_info($rel_name) or do {
3b4c4d72 1279 my $err = sprintf
1280 "Inflation into non-existent relationship '%s' of '%s' requested",
a5f5e470 1281 $rel_name,
3b4c4d72 1282 $rsrc->source_name,
1283 ;
a5f5e470 1284 if (my ($colname) = sort { length($a) <=> length ($b) } keys %{$prefetch->{$rel_name}[0] || {}} ) {
3b4c4d72 1285 $err .= sprintf ", check the inflation specification (columns/as) ending in '...%s.%s'",
a5f5e470 1286 $rel_name,
3b4c4d72 1287 $colname,
1288 }
1289
1290 $rsrc->throw_exception($err);
1291 };
1292
a5f5e470 1293 $class->throw_exception("No accessor type declared for prefetched relationship '$rel_name'")
3b4c4d72 1294 unless $relinfo->{attrs}{accessor};
1295
a5f5e470 1296 my $rel_rs = $new->related_resultset($rel_name);
93b306f0 1297
72c2540d 1298 my @rel_objects;
52864fbd 1299 if (
a5f5e470 1300 @{ $prefetch->{$rel_name} || [] }
52864fbd 1301 and
a5f5e470 1302 ref($prefetch->{$rel_name}) ne $DBIx::Class::ResultSource::RowParser::Util::null_branch_class
52864fbd 1303 ) {
25a942fa 1304
a5f5e470 1305 if (ref $prefetch->{$rel_name}[0] eq 'ARRAY') {
3b4c4d72 1306 my $rel_rsrc = $rel_rs->result_source;
1307 my $rel_class = $rel_rs->result_class;
1308 my $rel_inflator = $rel_class->can('inflate_result');
1309 @rel_objects = map
1310 { $rel_class->$rel_inflator ( $rel_rsrc, @$_ ) }
a5f5e470 1311 @{$prefetch->{$rel_name}}
3b4c4d72 1312 ;
1313 }
1314 else {
1315 @rel_objects = $rel_rs->result_class->inflate_result(
a5f5e470 1316 $rel_rs->result_source, @{$prefetch->{$rel_name}}
3b4c4d72 1317 );
1318 }
ce556881 1319 }
908aa1bb 1320
3b4c4d72 1321 if ($relinfo->{attrs}{accessor} eq 'single') {
a5f5e470 1322 $new->{_relationship_data}{$rel_name} = $rel_objects[0];
ce556881 1323 }
3b4c4d72 1324 elsif ($relinfo->{attrs}{accessor} eq 'filter') {
a5f5e470 1325 $new->{_inflated_column}{$rel_name} = $rel_objects[0];
ce556881 1326 }
b82c8a28 1327
93b306f0 1328 $rel_rs->set_cache(\@rel_objects);
b52e9bf8 1329 }
1330 }
35c77aa3 1331
1332 $new->in_storage (1);
7624b19f 1333 return $new;
1334}
1335
9b465d00 1336=head2 update_or_insert
7624b19f 1337
47d7b769 1338 $result->update_or_insert
a2531bf2 1339
1340=over
7624b19f 1341
a2531bf2 1342=item Arguments: none
1343
fb13a49f 1344=item Return Value: Result of update or insert operation
a2531bf2 1345
1346=back
1347
5529838f 1348L</update>s the object if it's already in the database, according to
a2531bf2 1349L</in_storage>, else L</insert>s it.
7624b19f 1350
9b83fccd 1351=head2 insert_or_update
1352
1353 $obj->insert_or_update
1354
1355Alias for L</update_or_insert>
1356
7624b19f 1357=cut
1358
370f2ba2 1359sub insert_or_update { shift->update_or_insert(@_) }
1360
9b465d00 1361sub update_or_insert {
7624b19f 1362 my $self = shift;
1363 return ($self->in_storage ? $self->update : $self->insert);
1364}
1365
8091aa91 1366=head2 is_changed
7624b19f 1367
47d7b769 1368 my @changed_col_names = $result->is_changed();
1369 if ($result->is_changed()) { ... }
a2531bf2 1370
1371=over
7624b19f 1372
a2531bf2 1373=item Arguments: none
1374
fb13a49f 1375=item Return Value: 0|1 or @columnnames
a2531bf2 1376
1377=back
1378
1379In list context returns a list of columns with uncommited changes, or
9b83fccd 1380in scalar context returns a true value if there are uncommitted
1381changes.
1382
7624b19f 1383=cut
1384
1385sub is_changed {
1386 return keys %{shift->{_dirty_columns} || {}};
1387}
228dbcb4 1388
1389=head2 is_column_changed
1390
47d7b769 1391 if ($result->is_column_changed('col')) { ... }
a2531bf2 1392
1393=over
1394
1395=item Arguments: $columname
1396
fb13a49f 1397=item Return Value: 0|1
a2531bf2 1398
1399=back
228dbcb4 1400
9b83fccd 1401Returns a true value if the column has uncommitted changes.
1402
228dbcb4 1403=cut
1404
1405sub is_column_changed {
1406 my( $self, $col ) = @_;
1407 return exists $self->{_dirty_columns}->{$col};
1408}
7624b19f 1409
097d3227 1410=head2 result_source
1411
47d7b769 1412 my $resultsource = $result->result_source;
a2531bf2 1413
1414=over
1415
fb13a49f 1416=item Arguments: L<$result_source?|DBIx::Class::ResultSource>
097d3227 1417
fb13a49f 1418=item Return Value: L<$result_source|DBIx::Class::ResultSource>
a2531bf2 1419
1420=back
1421
1422Accessor to the L<DBIx::Class::ResultSource> this object was created from.
87c4e602 1423
aec3eff1 1424=cut
1425
1426sub result_source {
5298bbb5 1427 $_[0]->throw_exception( 'result_source can be called on instances only' )
1428 unless ref $_[0];
1429
1430 @_ > 1
1431 ? $_[0]->{_result_source} = $_[1]
1432
1433 # note this is a || not a ||=, the difference is important
1434 : $_[0]->{_result_source} || do {
5298bbb5 1435 $_[0]->can('result_source_instance')
1436 ? $_[0]->result_source_instance
1437 : $_[0]->throw_exception(
b4ba5147 1438 "No result source instance registered for @{[ ref $_[0] ]}, did you forget to call @{[ ref $_[0] ]}->table(...) ?"
5298bbb5 1439 )
1440 }
1441 ;
aec3eff1 1442}
1443
9b83fccd 1444=head2 register_column
27f01d1f 1445
9b83fccd 1446 $column_info = { .... };
1447 $class->register_column($column_name, $column_info);
27f01d1f 1448
a2531bf2 1449=over
1450
1451=item Arguments: $columnname, \%columninfo
1452
fb13a49f 1453=item Return Value: not defined
a2531bf2 1454
1455=back
1456
9b83fccd 1457Registers a column on the class. If the column_info has an 'accessor'
1458key, creates an accessor named after the value if defined; if there is
1459no such key, creates an accessor with the same name as the column
1f23a877 1460
9b83fccd 1461The column_info attributes are described in
1462L<DBIx::Class::ResultSource/add_columns>
1f23a877 1463
097d3227 1464=cut
1465
1f23a877 1466sub register_column {
1467 my ($class, $col, $info) = @_;
91b0fbd7 1468 my $acc = $col;
1469 if (exists $info->{accessor}) {
1470 return unless defined $info->{accessor};
1471 $acc = [ $info->{accessor}, $col ];
1472 }
1473 $class->mk_group_accessors('column' => $acc);
1f23a877 1474}
1475
a2531bf2 1476=head2 get_from_storage
1477
47d7b769 1478 my $copy = $result->get_from_storage($attrs)
a2531bf2 1479
1480=over
b9b4e52f 1481
a2531bf2 1482=item Arguments: \%attrs
b9b4e52f 1483
fb13a49f 1484=item Return Value: A Result object
a2531bf2 1485
1486=back
1487
fb13a49f 1488Fetches a fresh copy of the Result object from the database and returns it.
d6988be8 1489Throws an exception if a proper WHERE clause identifying the database row
1490can not be constructed (i.e. if the original object does not contain its
1491entire
1492 L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>
1493). If passed the \%attrs argument, will first apply these attributes to
a2531bf2 1494the resultset used to find the row.
1495
fb13a49f 1496This copy can then be used to compare to an existing result object, to
a2531bf2 1497determine if any changes have been made in the database since it was
1498created.
1499
fb13a49f 1500To just update your Result object with any latest changes from the
a2531bf2 1501database, use L</discard_changes> instead.
1502
1503The \%attrs argument should be compatible with
1504L<DBIx::Class::ResultSet/ATTRIBUTES>.
7e38d850 1505
b9b4e52f 1506=cut
1507
a737512c 1508sub get_from_storage {
b9b4e52f 1509 my $self = shift @_;
7e38d850 1510 my $attrs = shift @_;
7e38d850 1511 my $resultset = $self->result_source->resultset;
b6d347e0 1512
7e38d850 1513 if(defined $attrs) {
bbd107cf 1514 $resultset = $resultset->search(undef, $attrs);
7e38d850 1515 }
b6d347e0 1516
867f1b28 1517 return $resultset->find($self->_storage_ident_condition);
b9b4e52f 1518}
701da8c4 1519
93711422 1520=head2 discard_changes
fde05eb9 1521
47d7b769 1522 $result->discard_changes
fde05eb9 1523
1524=over
1525
1526=item Arguments: none or $attrs
1527
fb13a49f 1528=item Return Value: self (updates object in-place)
fde05eb9 1529
1530=back
bbd107cf 1531
1532Re-selects the row from the database, losing any changes that had
fde05eb9 1533been made. Throws an exception if a proper C<WHERE> clause identifying
d6988be8 1534the database row can not be constructed (i.e. if the original object
1535does not contain its entire
fde05eb9 1536L<primary key|DBIx::Class::Manual::Intro/The Significance and Importance of Primary Keys>).
bbd107cf 1537
1538This method can also be used to refresh from storage, retrieving any
1539changes made since the row was last read from storage.
1540
fde05eb9 1541$attrs, if supplied, is expected to be a hashref of attributes suitable for passing as the
1542second argument to C<< $resultset->search($cond, $attrs) >>;
1543
1544Note: If you are using L<DBIx::Class::Storage::DBI::Replicated> as your
3dd506b8 1545storage, a default of
1546L<< C<< { force_pool => 'master' } >>
1547|DBIx::Class::Storage::DBI::Replicated/SYNOPSIS >> is automatically set for
1548you. Prior to C<< DBIx::Class 0.08109 >> (before 2010) one would have been
1549required to explicitly wrap the entire operation in a transaction to guarantee
1550that up-to-date results are read from the master database.
bbd107cf 1551
1552=cut
1553
1554sub discard_changes {
1555 my ($self, $attrs) = @_;
bbd107cf 1556 return unless $self->in_storage; # Don't reload if we aren't real!
1557
1558 # add a replication default to read from the master only
1559 $attrs = { force_pool => 'master', %{$attrs||{}} };
1560
1561 if( my $current_storage = $self->get_from_storage($attrs)) {
1562
1563 # Set $self to the current.
1564 %$self = %$current_storage;
1565
1566 # Avoid a possible infinite loop with
1567 # sub DESTROY { $_[0]->discard_changes }
1568 bless $current_storage, 'Do::Not::Exist';
1569
1570 return $self;
1571 }
1572 else {
1573 $self->in_storage(0);
1574 return $self;
1575 }
1576}
1577
5160b401 1578=head2 throw_exception
701da8c4 1579
a2531bf2 1580See L<DBIx::Class::Schema/throw_exception>.
701da8c4 1581
1582=cut
1583
1584sub throw_exception {
1585 my $self=shift;
1a58752c 1586
ddcc02d1 1587 if (
1588 ref $self
1589 and
1590 my $rsrc = dbic_internal_try { $self->result_source_instance }
1591 ) {
4f52479b 1592 $rsrc->throw_exception(@_)
1a58752c 1593 }
1594 else {
1595 DBIx::Class::Exception->throw(@_);
701da8c4 1596 }
1597}
1598
33cf6616 1599=head2 id
1600
47d7b769 1601 my @pk = $result->id;
a2531bf2 1602
1603=over
1604
1605=item Arguments: none
1606
1607=item Returns: A list of primary key values
1608
1609=back
1610
33cf6616 1611Returns the primary key(s) for a row. Can't be called as a class method.
f7043881 1612Actually implemented in L<DBIx::Class::PK>
33cf6616 1613
a2bd3796 1614=head1 FURTHER QUESTIONS?
7624b19f 1615
a2bd3796 1616Check the list of L<additional DBIC resources|DBIx::Class/GETTING HELP/SUPPORT>.
7624b19f 1617
a2bd3796 1618=head1 COPYRIGHT AND LICENSE
7624b19f 1619
a2bd3796 1620This module is free software L<copyright|DBIx::Class/COPYRIGHT AND LICENSE>
1621by the L<DBIx::Class (DBIC) authors|DBIx::Class/AUTHORS>. You can
1622redistribute it and/or modify it under the same terms as the
1623L<DBIx::Class library|DBIx::Class/COPYRIGHT AND LICENSE>.
7624b19f 1624
1625=cut
fde05eb9 1626
16271;