Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/DBIx/Class/InflateColumn.pm |
Statements | Executed 4468 statements in 16.1ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
441 | 2 | 2 | 9.75ms | 142ms | set_inflated_column | DBIx::Class::InflateColumn::
588 | 2 | 2 | 4.86ms | 73.8ms | _deflated_column | DBIx::Class::InflateColumn::
38 | 5 | 5 | 1.21ms | 6.06ms | inflate_column | DBIx::Class::InflateColumn::
1 | 1 | 1 | 16µs | 21µs | BEGIN@3 | DBIx::Class::InflateColumn::
1 | 1 | 1 | 9µs | 26µs | BEGIN@4 | DBIx::Class::InflateColumn::
1 | 1 | 1 | 8µs | 5.63ms | BEGIN@6 | DBIx::Class::InflateColumn::
0 | 0 | 0 | 0s | 0s | _inflated_column | DBIx::Class::InflateColumn::
0 | 0 | 0 | 0s | 0s | get_inflated_column | DBIx::Class::InflateColumn::
0 | 0 | 0 | 0s | 0s | store_inflated_column | DBIx::Class::InflateColumn::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package DBIx::Class::InflateColumn; | ||||
2 | |||||
3 | 3 | 21µs | 2 | 25µs | # spent 21µs (16+4) within DBIx::Class::InflateColumn::BEGIN@3 which was called:
# once (16µs+4µs) by Class::C3::Componentised::ensure_class_loaded at line 3 # spent 21µs making 1 call to DBIx::Class::InflateColumn::BEGIN@3
# spent 4µs making 1 call to strict::import |
4 | 3 | 23µs | 2 | 42µs | # spent 26µs (9+16) within DBIx::Class::InflateColumn::BEGIN@4 which was called:
# once (9µs+16µs) by Class::C3::Componentised::ensure_class_loaded at line 4 # spent 26µs making 1 call to DBIx::Class::InflateColumn::BEGIN@4
# spent 16µs making 1 call to warnings::import |
5 | |||||
6 | 3 | 423µs | 2 | 11.2ms | # spent 5.63ms (8µs+5.62) within DBIx::Class::InflateColumn::BEGIN@6 which was called:
# once (8µs+5.62ms) by Class::C3::Componentised::ensure_class_loaded at line 6 # spent 5.63ms making 1 call to DBIx::Class::InflateColumn::BEGIN@6
# spent 5.62ms making 1 call to base::import |
7 | |||||
8 | =head1 NAME | ||||
9 | |||||
10 | DBIx::Class::InflateColumn - Automatically create references from column data | ||||
11 | |||||
12 | =head1 SYNOPSIS | ||||
13 | |||||
14 | # In your table classes | ||||
15 | __PACKAGE__->inflate_column('column_name', { | ||||
16 | inflate => sub { ... }, | ||||
17 | deflate => sub { ... }, | ||||
18 | }); | ||||
19 | |||||
20 | =head1 DESCRIPTION | ||||
21 | |||||
22 | This component translates column data into references, i.e. "inflating" | ||||
23 | the column data. It also "deflates" references into an appropriate format | ||||
24 | for the database. | ||||
25 | |||||
26 | It can be used, for example, to automatically convert to and from | ||||
27 | L<DateTime> objects for your date and time fields. There's a | ||||
28 | convenience component to actually do that though, try | ||||
29 | L<DBIx::Class::InflateColumn::DateTime>. | ||||
30 | |||||
31 | It will handle all types of references except scalar references. It | ||||
32 | will not handle scalar values, these are ignored and thus passed | ||||
33 | through to L<SQL::Abstract>. This is to allow setting raw values to | ||||
34 | "just work". Scalar references are passed through to the database to | ||||
35 | deal with, to allow such settings as C< \'year + 1'> and C< \'DEFAULT' > | ||||
36 | to work. | ||||
37 | |||||
38 | If you want to filter plain scalar values and replace them with | ||||
39 | something else, see L<DBIx::Class::FilterColumn>. | ||||
40 | |||||
41 | =head1 METHODS | ||||
42 | |||||
43 | =head2 inflate_column | ||||
44 | |||||
45 | Instruct L<DBIx::Class> to inflate the given column. | ||||
46 | |||||
47 | In addition to the column name, you must provide C<inflate> and | ||||
48 | C<deflate> methods. The C<inflate> method is called when you access | ||||
49 | the field, while the C<deflate> method is called when the field needs | ||||
50 | to used by the database. | ||||
51 | |||||
52 | For example, if you have a table C<events> with a timestamp field | ||||
53 | named C<insert_time>, you could inflate the column in the | ||||
54 | corresponding table class using something like: | ||||
55 | |||||
56 | __PACKAGE__->inflate_column('insert_time', { | ||||
57 | inflate => sub { DateTime::Format::Pg->parse_datetime(shift); }, | ||||
58 | deflate => sub { DateTime::Format::Pg->format_datetime(shift); }, | ||||
59 | }); | ||||
60 | |||||
61 | (Replace L<DateTime::Format::Pg> with the appropriate module for your | ||||
62 | database, or consider L<DateTime::Format::DBI>.) | ||||
63 | |||||
64 | The coderefs you set for inflate and deflate are called with two parameters, | ||||
65 | the first is the value of the column to be inflated/deflated, the second is the | ||||
66 | row object itself. Thus you can call C<< ->result_source->schema->storage->dbh >> in your inflate/defalte subs, to feed to L<DateTime::Format::DBI>. | ||||
67 | |||||
68 | In this example, calls to an event's C<insert_time> accessor return a | ||||
69 | L<DateTime> object. This L<DateTime> object is later "deflated" when | ||||
70 | used in the database layer. | ||||
71 | |||||
72 | =cut | ||||
73 | |||||
74 | # spent 6.06ms (1.21+4.85) within DBIx::Class::InflateColumn::inflate_column which was called 38 times, avg 159µs/call:
# 34 times (1.10ms+4.19ms) by DBIx::Class::InflateColumn::DateTime::register_column at line 189 of DBIx/Class/InflateColumn/DateTime.pm, avg 156µs/call
# once (74µs+205µs) by DBIx::Class::InflateColumn::Object::Enum::register_column at line 114 of DBIx/Class/InflateColumn/Object/Enum.pm
# once (11µs+178µs) by Class::C3::Componentised::ensure_class_loaded at line 28 of Tapper/Schema/TestrunDB/Result/Message.pm
# once (11µs+175µs) by Class::C3::Componentised::ensure_class_loaded at line 27 of Tapper/Schema/TestrunDB/Result/State.pm
# once (11µs+103µs) by Class::C3::Componentised::ensure_class_loaded at line 30 of Tapper/Schema/ReportsDB/Result/NotificationEvent.pm | ||||
75 | 342 | 1.38ms | my ($self, $col, $attrs) = @_; | ||
76 | |||||
77 | 38 | 850µs | my $colinfo = $self->column_info($col); # spent 850µs making 38 calls to DBIx::Class::ResultSourceProxy::column_info, avg 22µs/call | ||
78 | |||||
79 | 38 | 225µs | $self->throw_exception("InflateColumn does not work with FilterColumn") # spent 225µs making 38 calls to UNIVERSAL::isa, avg 6µs/call | ||
80 | if $self->isa('DBIx::Class::FilterColumn') && | ||||
81 | defined $colinfo->{_filter_info}; | ||||
82 | |||||
83 | 38 | 686µs | $self->throw_exception("No such column $col to inflate") # spent 686µs making 38 calls to DBIx::Class::ResultSourceProxy::has_column, avg 18µs/call | ||
84 | unless $self->has_column($col); | ||||
85 | $self->throw_exception("inflate_column needs attr hashref") | ||||
86 | unless ref $attrs eq 'HASH'; | ||||
87 | $colinfo->{_inflate_info} = $attrs; | ||||
88 | my $acc = $colinfo->{accessor}; | ||||
89 | 38 | 3.09ms | $self->mk_group_accessors('inflated_column' => [ (defined $acc ? $acc : $col), $col]); # spent 3.09ms making 38 calls to Class::Accessor::Grouped::mk_group_accessors, avg 81µs/call | ||
90 | return 1; | ||||
91 | } | ||||
92 | |||||
93 | sub _inflated_column { | ||||
94 | my ($self, $col, $value) = @_; | ||||
95 | return $value unless defined $value; # NULL is NULL is NULL | ||||
96 | my $info = $self->column_info($col) | ||||
97 | or $self->throw_exception("No column info for $col"); | ||||
98 | return $value unless exists $info->{_inflate_info}; | ||||
99 | my $inflate = $info->{_inflate_info}{inflate}; | ||||
100 | $self->throw_exception("No inflator for $col") unless defined $inflate; | ||||
101 | return $inflate->($value, $self); | ||||
102 | } | ||||
103 | |||||
104 | # spent 73.8ms (4.86+68.9) within DBIx::Class::InflateColumn::_deflated_column which was called 588 times, avg 125µs/call:
# 441 times (2.75ms+0s) by DBIx::Class::InflateColumn::set_inflated_column at line 152, avg 6µs/call
# 147 times (2.11ms+68.9ms) by DBIx::Class::Row::get_columns at line 674 of DBIx/Class/Row.pm, avg 483µs/call | ||||
105 | 1911 | 5.87ms | my ($self, $col, $value) = @_; | ||
106 | # return $value unless ref $value && blessed($value); # If it's not an object, don't touch it | ||||
107 | ## Leave scalar refs (ala SQL::Abstract literal SQL), untouched, deflate all other refs | ||||
108 | return $value unless (ref $value && ref($value) ne 'SCALAR'); | ||||
109 | 147 | 6.43ms | my $info = $self->column_info($col) or # spent 6.43ms making 147 calls to DBIx::Class::ResultSourceProxy::column_info, avg 44µs/call | ||
110 | $self->throw_exception("No column info for $col"); | ||||
111 | return $value unless exists $info->{_inflate_info}; | ||||
112 | my $deflate = $info->{_inflate_info}{deflate}; | ||||
113 | $self->throw_exception("No deflator for $col") unless defined $deflate; | ||||
114 | 147 | 62.5ms | return $deflate->($value, $self); # spent 62.5ms making 147 calls to DBIx::Class::InflateColumn::DateTime::__ANON__[DBIx/Class/InflateColumn/DateTime.pm:187], avg 425µs/call | ||
115 | } | ||||
116 | |||||
117 | =head2 get_inflated_column | ||||
118 | |||||
119 | my $val = $obj->get_inflated_column($col); | ||||
120 | |||||
121 | Fetch a column value in its inflated state. This is directly | ||||
122 | analogous to L<DBIx::Class::Row/get_column> in that it only fetches a | ||||
123 | column already retrieved from the database, and then inflates it. | ||||
124 | Throws an exception if the column requested is not an inflated column. | ||||
125 | |||||
126 | =cut | ||||
127 | |||||
128 | sub get_inflated_column { | ||||
129 | my ($self, $col) = @_; | ||||
130 | $self->throw_exception("$col is not an inflated column") | ||||
131 | unless exists $self->column_info($col)->{_inflate_info}; | ||||
132 | return $self->{_inflated_column}{$col} | ||||
133 | if exists $self->{_inflated_column}{$col}; | ||||
134 | |||||
135 | my $val = $self->get_column($col); | ||||
136 | return $val if ref $val eq 'SCALAR'; #that would be a not-yet-reloaded sclarref update | ||||
137 | |||||
138 | return $self->{_inflated_column}{$col} = $self->_inflated_column($col, $val); | ||||
139 | } | ||||
140 | |||||
141 | =head2 set_inflated_column | ||||
142 | |||||
143 | my $copy = $obj->set_inflated_column($col => $val); | ||||
144 | |||||
145 | Sets a column value from an inflated value. This is directly | ||||
146 | analogous to L<DBIx::Class::Row/set_column>. | ||||
147 | |||||
148 | =cut | ||||
149 | |||||
150 | # spent 142ms (9.75+133) within DBIx::Class::InflateColumn::set_inflated_column which was called 441 times, avg 323µs/call:
# 294 times (6.39ms+95.8ms) by Tapper::Schema::TestrunDB::Result::TestrunScheduling::status at line 2 of (eval 307)[Class/Accessor/Grouped.pm:807], avg 348µs/call
# 147 times (3.36ms+36.7ms) by Tapper::Schema::TestrunDB::Result::Testrun::starttime_testrun at line 2 of (eval 382)[Class/Accessor/Grouped.pm:807], avg 273µs/call | ||||
151 | 2205 | 8.39ms | my ($self, $col, $inflated) = @_; | ||
152 | 882 | 133ms | $self->set_column($col, $self->_deflated_column($col, $inflated)); # spent 130ms making 441 calls to DBIx::Class::Row::set_column, avg 294µs/call
# spent 2.75ms making 441 calls to DBIx::Class::InflateColumn::_deflated_column, avg 6µs/call | ||
153 | # if (blessed $inflated) { | ||||
154 | if (ref $inflated && ref($inflated) ne 'SCALAR') { | ||||
155 | $self->{_inflated_column}{$col} = $inflated; | ||||
156 | } else { | ||||
157 | delete $self->{_inflated_column}{$col}; | ||||
158 | } | ||||
159 | return $inflated; | ||||
160 | } | ||||
161 | |||||
162 | =head2 store_inflated_column | ||||
163 | |||||
164 | my $copy = $obj->store_inflated_column($col => $val); | ||||
165 | |||||
166 | Sets a column value from an inflated value without marking the column | ||||
167 | as dirty. This is directly analogous to L<DBIx::Class::Row/store_column>. | ||||
168 | |||||
169 | =cut | ||||
170 | |||||
171 | sub store_inflated_column { | ||||
172 | my ($self, $col, $inflated) = @_; | ||||
173 | # unless (blessed $inflated) { | ||||
174 | unless (ref $inflated && ref($inflated) ne 'SCALAR') { | ||||
175 | delete $self->{_inflated_column}{$col}; | ||||
176 | $self->store_column($col => $inflated); | ||||
177 | return $inflated; | ||||
178 | } | ||||
179 | delete $self->{_column_data}{$col}; | ||||
180 | return $self->{_inflated_column}{$col} = $inflated; | ||||
181 | } | ||||
182 | |||||
183 | =head1 SEE ALSO | ||||
184 | |||||
185 | =over 4 | ||||
186 | |||||
187 | =item L<DBIx::Class::Core> - This component is loaded as part of the | ||||
188 | C<core> L<DBIx::Class> components; generally there is no need to | ||||
189 | load it directly | ||||
190 | |||||
191 | =back | ||||
192 | |||||
193 | =head1 AUTHOR | ||||
194 | |||||
195 | Matt S. Trout <mst@shadowcatsystems.co.uk> | ||||
196 | |||||
197 | =head1 CONTRIBUTORS | ||||
198 | |||||
199 | Daniel Westermann-Clark <danieltwc@cpan.org> (documentation) | ||||
200 | |||||
201 | Jess Robinson <cpan@desert-island.demon.co.uk> | ||||
202 | |||||
203 | =head1 LICENSE | ||||
204 | |||||
205 | You may distribute this code under the same terms as Perl itself. | ||||
206 | |||||
207 | =cut | ||||
208 | |||||
209 | 1 | 3µs | 1; |