File Coverage

blib/lib/DBIx/Class/Row.pm
Criterion Covered Total %
statement 361 381 94.7
branch 185 218 84.8
condition 106 140 75.7
subroutine 43 44 97.7
pod 25 25 100.0
total 720 808 89.1


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