File | /wise/base/static/lib/perl5/site_perl/5.10.0/DBIx/Class/InflateColumn.pm | Statements Executed | 13 | Total Time | 0.000658 seconds |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine | |
---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | BEGIN |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | _deflated_column |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | _inflated_column |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | get_inflated_column |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | inflate_column |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | set_inflated_column |
0 | 0 | 0 | 0 | 0 | DBIx::Class::InflateColumn:: | store_inflated_column |
Line | Stmts. | Exclusive Time | Avg. | Code |
---|---|---|---|---|
1 | package DBIx::Class::InflateColumn; | |||
2 | ||||
3 | 3 | 3.3e-5 | 1.1e-5 | use strict; # spent 11µs making 1 call to strict::import |
4 | 3 | 5.7e-5 | 1.9e-5 | use warnings; # spent 36µs making 1 call to warnings::import |
5 | 3 | 4.3e-5 | 1.4e-5 | use Scalar::Util qw/blessed/; # spent 58µs making 1 call to Exporter::import |
6 | ||||
7 | 3 | 0.00052 | 0.00017 | use base qw/DBIx::Class::Row/; # spent 6.22ms making 1 call to base::import |
8 | ||||
9 | =head1 NAME | |||
10 | ||||
11 | DBIx::Class::InflateColumn - Automatically create references from column data | |||
12 | ||||
13 | =head1 SYNOPSIS | |||
14 | ||||
15 | # In your table classes | |||
16 | __PACKAGE__->inflate_column('column_name', { | |||
17 | inflate => sub { ... }, | |||
18 | deflate => sub { ... }, | |||
19 | }); | |||
20 | ||||
21 | =head1 DESCRIPTION | |||
22 | ||||
23 | This component translates column data into references, i.e. "inflating" | |||
24 | the column data. It also "deflates" references into an appropriate format | |||
25 | for the database. | |||
26 | ||||
27 | It can be used, for example, to automatically convert to and from | |||
28 | L<DateTime> objects for your date and time fields. There's a | |||
29 | conveniece component to actually do that though, try | |||
30 | L<DBIx::Class::InflateColumn::DateTime>. | |||
31 | ||||
32 | It will handle all types of references except scalar references. It | |||
33 | will not handle scalar values, these are ignored and thus passed | |||
34 | through to L<SQL::Abstract>. This is to allow setting raw values to | |||
35 | "just work". Scalar references are passed through to the database to | |||
36 | deal with, to allow such settings as C< \'year + 1'> and C< \'DEFAULT' > | |||
37 | to work. | |||
38 | ||||
39 | If you want to filter plain scalar values and replace them with | |||
40 | something else, contribute a filtering component. | |||
41 | ||||
42 | =head1 METHODS | |||
43 | ||||
44 | =head2 inflate_column | |||
45 | ||||
46 | Instruct L<DBIx::Class> to inflate the given column. | |||
47 | ||||
48 | In addition to the column name, you must provide C<inflate> and | |||
49 | C<deflate> methods. The C<inflate> method is called when you access | |||
50 | the field, while the C<deflate> method is called when the field needs | |||
51 | to used by the database. | |||
52 | ||||
53 | For example, if you have a table C<events> with a timestamp field | |||
54 | named C<insert_time>, you could inflate the column in the | |||
55 | corresponding table class using something like: | |||
56 | ||||
57 | __PACKAGE__->inflate_column('insert_time', { | |||
58 | inflate => sub { DateTime::Format::Pg->parse_datetime(shift); }, | |||
59 | deflate => sub { DateTime::Format::Pg->format_datetime(shift); }, | |||
60 | }); | |||
61 | ||||
62 | (Replace L<DateTime::Format::Pg> with the appropriate module for your | |||
63 | database, or consider L<DateTime::Format::DBI>.) | |||
64 | ||||
65 | The coderefs you set for inflate and deflate are called with two parameters, | |||
66 | the first is the value of the column to be inflated/deflated, the second is the | |||
67 | 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>. | |||
68 | ||||
69 | In this example, calls to an event's C<insert_time> accessor return a | |||
70 | L<DateTime> object. This L<DateTime> object is later "deflated" when | |||
71 | used in the database layer. | |||
72 | ||||
73 | =cut | |||
74 | ||||
75 | sub inflate_column { | |||
76 | my ($self, $col, $attrs) = @_; | |||
77 | $self->throw_exception("No such column $col to inflate") | |||
78 | unless $self->has_column($col); | |||
79 | $self->throw_exception("inflate_column needs attr hashref") | |||
80 | unless ref $attrs eq 'HASH'; | |||
81 | $self->column_info($col)->{_inflate_info} = $attrs; | |||
82 | $self->mk_group_accessors('inflated_column' => [$self->column_info($col)->{accessor} || $col, $col]); | |||
83 | return 1; | |||
84 | } | |||
85 | ||||
86 | sub _inflated_column { | |||
87 | my ($self, $col, $value) = @_; | |||
88 | return $value unless defined $value; # NULL is NULL is NULL | |||
89 | my $info = $self->column_info($col) | |||
90 | or $self->throw_exception("No column info for $col"); | |||
91 | return $value unless exists $info->{_inflate_info}; | |||
92 | my $inflate = $info->{_inflate_info}{inflate}; | |||
93 | $self->throw_exception("No inflator for $col") unless defined $inflate; | |||
94 | return $inflate->($value, $self); | |||
95 | } | |||
96 | ||||
97 | sub _deflated_column { | |||
98 | my ($self, $col, $value) = @_; | |||
99 | # return $value unless ref $value && blessed($value); # If it's not an object, don't touch it | |||
100 | ## Leave scalar refs (ala SQL::Abstract literal SQL), untouched, deflate all other refs | |||
101 | return $value unless (ref $value && ref($value) ne 'SCALAR'); | |||
102 | my $info = $self->column_info($col) or | |||
103 | $self->throw_exception("No column info for $col"); | |||
104 | return $value unless exists $info->{_inflate_info}; | |||
105 | my $deflate = $info->{_inflate_info}{deflate}; | |||
106 | $self->throw_exception("No deflator for $col") unless defined $deflate; | |||
107 | return $deflate->($value, $self); | |||
108 | } | |||
109 | ||||
110 | =head2 get_inflated_column | |||
111 | ||||
112 | my $val = $obj->get_inflated_column($col); | |||
113 | ||||
114 | Fetch a column value in its inflated state. This is directly | |||
115 | analogous to L<DBIx::Class::Row/get_column> in that it only fetches a | |||
116 | column already retreived from the database, and then inflates it. | |||
117 | Throws an exception if the column requested is not an inflated column. | |||
118 | ||||
119 | =cut | |||
120 | ||||
121 | sub get_inflated_column { | |||
122 | my ($self, $col) = @_; | |||
123 | $self->throw_exception("$col is not an inflated column") | |||
124 | unless exists $self->column_info($col)->{_inflate_info}; | |||
125 | return $self->{_inflated_column}{$col} | |||
126 | if exists $self->{_inflated_column}{$col}; | |||
127 | return $self->{_inflated_column}{$col} = | |||
128 | $self->_inflated_column($col, $self->get_column($col)); | |||
129 | } | |||
130 | ||||
131 | =head2 set_inflated_column | |||
132 | ||||
133 | my $copy = $obj->set_inflated_column($col => $val); | |||
134 | ||||
135 | Sets a column value from an inflated value. This is directly | |||
136 | analogous to L<DBIx::Class::Row/set_column>. | |||
137 | ||||
138 | =cut | |||
139 | ||||
140 | sub set_inflated_column { | |||
141 | my ($self, $col, $inflated) = @_; | |||
142 | $self->set_column($col, $self->_deflated_column($col, $inflated)); | |||
143 | # if (blessed $inflated) { | |||
144 | if (ref $inflated && ref($inflated) ne 'SCALAR') { | |||
145 | $self->{_inflated_column}{$col} = $inflated; | |||
146 | } else { | |||
147 | delete $self->{_inflated_column}{$col}; | |||
148 | } | |||
149 | return $inflated; | |||
150 | } | |||
151 | ||||
152 | =head2 store_inflated_column | |||
153 | ||||
154 | my $copy = $obj->store_inflated_column($col => $val); | |||
155 | ||||
156 | Sets a column value from an inflated value without marking the column | |||
157 | as dirty. This is directly analogous to L<DBIx::Class::Row/store_column>. | |||
158 | ||||
159 | =cut | |||
160 | ||||
161 | sub store_inflated_column { | |||
162 | my ($self, $col, $inflated) = @_; | |||
163 | # unless (blessed $inflated) { | |||
164 | unless (ref $inflated && ref($inflated) ne 'SCALAR') { | |||
165 | delete $self->{_inflated_column}{$col}; | |||
166 | $self->store_column($col => $inflated); | |||
167 | return $inflated; | |||
168 | } | |||
169 | delete $self->{_column_data}{$col}; | |||
170 | return $self->{_inflated_column}{$col} = $inflated; | |||
171 | } | |||
172 | ||||
173 | =head1 SEE ALSO | |||
174 | ||||
175 | =over 4 | |||
176 | ||||
177 | =item L<DBIx::Class::Core> - This component is loaded as part of the | |||
178 | "core" L<DBIx::Class> components; generally there is no need to | |||
179 | load it directly | |||
180 | ||||
181 | =back | |||
182 | ||||
183 | =head1 AUTHOR | |||
184 | ||||
185 | Matt S. Trout <mst@shadowcatsystems.co.uk> | |||
186 | ||||
187 | =head1 CONTRIBUTORS | |||
188 | ||||
189 | Daniel Westermann-Clark <danieltwc@cpan.org> (documentation) | |||
190 | ||||
191 | Jess Robinson <cpan@desert-island.demon.co.uk> | |||
192 | ||||
193 | =head1 LICENSE | |||
194 | ||||
195 | You may distribute this code under the same terms as Perl itself. | |||
196 | ||||
197 | =cut | |||
198 | ||||
199 | 1 | 3.0e-6 | 3.0e-6 | 1; |