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$column_accessor>.
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;