File Coverage

blib/lib/DBIx/Class/Helper/Row/OnColumnMissing.pm
Criterion Covered Total %
statement 19 20 95.0
branch 5 6 83.3
condition n/a
subroutine 7 8 87.5
pod 1 5 20.0
total 32 39 82.0


line stmt bran cond sub pod time code
1             package DBIx::Class::Helper::Row::OnColumnMissing;
2             $DBIx::Class::Helper::Row::OnColumnMissing::VERSION = '2.035000';
3             # ABSTRACT: Configurably handle access of missing columns
4              
5 56     56   107298 use strict;
  56         133  
  56         1690  
6 56     56   300 use warnings;
  56         195  
  56         1504  
7              
8 56     56   297 use parent 'DBIx::Class::Row';
  56         127  
  56         292  
9              
10 0     0 0 0 sub on_column_missing { 'warn' }
11              
12 1     1 0 14 sub on_column_missing_die { die "Column $_[1] has not been loaded" }
13 1     1 0 15 sub on_column_missing_warn { warn "Column $_[1] has not been loaded" }
14       2 0   sub on_column_missing_nothing {}
15              
16             sub get_column {
17 40     40 1 61252 my ($self, $column_name) = @_;
18              
19 40 100       202 if ($self->has_column_loaded($column_name)) {
20 35         389 $self->next::method($column_name)
21             } else {
22 5         53 my $action = $self->on_column_missing;
23 5 100       26 unless (ref $action) {
24 4 50       15 $action = "on_column_missing_$action" unless ref $action;
25 4         33 $action = $self->can($action);
26             }
27 5         19 scalar $self->$action($column_name)
28             }
29             }
30              
31              
32             1;
33              
34             __END__
35              
36             =pod
37              
38             =head1 NAME
39              
40             DBIx::Class::Helper::Row::OnColumnMissing - Configurably handle access of missing columns
41              
42             =head1 SYNOPSIS
43              
44             package MyApp::Schema::Result::Account;
45              
46             use parent 'DBIx::Class::Core';
47              
48             __PACKAGE__->load_components(qw(Helper::Row::OnColumnMissing));
49              
50             __PACKAGE__->table('Account');
51              
52             __PACKAGE__->add_columns(
53             id => {
54             data_type => 'integer',
55             is_auto_increment => 1,
56             },
57             name => {
58             data_type => 'varchar',
59             size => 25,
60             },
61             book => { data_type => 'text' },
62             );
63              
64             sub on_column_missing { 'die' }
65              
66             1;
67              
68             Or with L<DBIx::Class::Candy>:
69              
70             package MyApp::Schema::Result::Account;
71              
72             use DBIx::Class::Candy -components => ['Helper::Row::OnColumnMissing'];
73              
74             table 'Account';
75              
76             column id => {
77             data_type => 'integer',
78             is_auto_increment => 1,
79             };
80              
81             column amount => {
82             data_type => 'float',
83             keep_storage_value => 1,
84             };
85              
86             column book => { data_type => 'text' };
87              
88             sub on_column_missing { 'die' }
89              
90             1;
91              
92             Elsewhere:
93              
94             my $row = $rs->search(undef, { columns => [qw( id name )] })->one_row;
95              
96             $row->book # dies
97              
98             =head1 DESCRIPTION
99              
100             This module is written to handle the odd condition where you have limited the
101             columns retrieved from the database but accidentally access one of the ones not
102             included. It is configurable by tweaking the C<on_column_missing> return value.
103              
104             =head1 MODES
105              
106             You specify the C<mode> by returning the C<mode> from the C<on_column_missing>
107             method. By default the C<mode> returned is C<warn>.
108              
109             The predefined modes are:
110              
111             =over 2
112              
113             =item C<die>
114              
115             Dies with C<Column $name has not been loaded>.
116              
117             =item C<warn>
118              
119             Warns with C<Column $name has not been loaded>.
120              
121             =item C<nothing>
122              
123             Does nothing
124              
125             =back
126              
127             You can predefine more modes by defining methods named C<on_column_$mode>, and
128             also override the default modes by overriding the corresponding methods. If you
129             need ad-hoc behavior you can return a code reference and that will be called as
130             a method on the object.
131              
132             =head2 ADVANCED USAGE
133              
134             If for some reason you find that you need to change your C<mode> at runtime, you
135             can always replace the C<on_column_missing> with an accessor. For example:
136              
137             __PACKAGE__->mk_group_accessors(inherited => 'on_column_missing');
138             __PACKAGE__->on_column_missing('warn');
139              
140             Elsewhere:
141              
142             $row->on_column_missing('die');
143              
144             If you are especially crazy you could even do something like this:
145              
146             $row->on_column_missing(sub {
147             my ($self, $column) = @_;
148              
149             $self
150             ->result_source
151             ->resultset
152             ->search({ id => $self->id })
153             ->get_column($column)
154             ->single
155             });
156              
157             Though if you do that I would make it a named mode (maybe C<retrieve>?)
158              
159             =head1 THANKS
160              
161             Thanks L<ZipRecruiter|https://www.ziprecruiter.com> for funding the development
162             of this module.
163              
164             =head1 AUTHOR
165              
166             Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
167              
168             =head1 COPYRIGHT AND LICENSE
169              
170             This software is copyright (c) 2020 by Arthur Axel "fREW" Schmidt.
171              
172             This is free software; you can redistribute it and/or modify it under
173             the same terms as the Perl 5 programming language system itself.
174              
175             =cut