File Coverage

blib/lib/DBIx/Class/Row.pm
Criterion Covered Total %
statement 362 379 95.5
branch 188 222 84.6
condition 95 132 71.9
subroutine 43 45 95.5
pod 25 25 100.0
total 713 803 88.7


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