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