Renamed Table to ResultSource::Table, tweaked FAQ
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / InflateColumn.pm
CommitLineData
0e5c2582 1package DBIx::Class::InflateColumn;
2
3use strict;
4use warnings;
75a23b3e 5use base qw/DBIx::Class::Row/;
0e5c2582 6
bcae85db 7=head1 NAME
8
9DBIx::Class::InflateColumn - Automatically create objects from column data
10
11=head1 SYNOPSIS
12
13 # In your table classes
14 __PACKAGE__->inflate_column('column_name', {
15 inflate => sub { ... },
16 deflate => sub { ... },
17 });
18
19=head1 DESCRIPTION
20
21This component translates column data into objects, i.e. "inflating"
22the column data. It also "deflates" objects into an appropriate format
23for the database.
24
25It can be used, for example, to automatically convert to and from
26L<DateTime> objects for your date and time fields.
27
28=head1 METHODS
29
30=head2 inflate_column
31
32Instruct L<DBIx::Class> to inflate the given column.
33
34In addition to the column name, you must provide C<inflate> and
35C<deflate> methods. The C<inflate> method is called when you access
36the field, while the C<deflate> method is called when the field needs
37to used by the database.
38
39For example, if you have a table C<events> with a timestamp field
40named C<insert_time>, you could inflate the column in the
41corresponding table class using something like:
42
43 __PACKAGE__->inflate_column('insert_time', {
44 inflate => sub { DateTime::Format::Pg->parse_datetime(shift); },
45 deflate => sub { DateTime::Format::Pg->format_datetime(shift); },
46 });
47
48(Replace L<DateTime::Format::Pg> with the appropriate module for your
49database, or consider L<DateTime::Format::DBI>.)
50
51In this example, calls to an event's C<insert_time> accessor return a
52L<DateTime> object. This L<DateTime> object is later "deflated" when
53used in the database layer.
54
55=cut
56
0e5c2582 57sub inflate_column {
58 my ($self, $col, $attrs) = @_;
103647d5 59 die "No such column $col to inflate" unless $self->has_column($col);
0e5c2582 60 die "inflate_column needs attr hashref" unless ref $attrs eq 'HASH';
103647d5 61 $self->column_info($col)->{_inflate_info} = $attrs;
0e5c2582 62 $self->mk_group_accessors('inflated_column' => $col);
63 return 1;
64}
65
4a07648a 66sub _inflated_column {
0e5c2582 67 my ($self, $col, $value) = @_;
9f300b1b 68 return $value unless defined $value; # NULL is NULL is NULL
103647d5 69 my $info = $self->column_info($col) || die "No column info for $col";
70 return $value unless exists $info->{_inflate_info};
71 my $inflate = $info->{_inflate_info}{inflate};
72 die "No inflator for $col" unless defined $inflate;
0e5c2582 73 return $inflate->($value, $self);
74}
75
4a07648a 76sub _deflated_column {
0e5c2582 77 my ($self, $col, $value) = @_;
78 return $value unless ref $value; # If it's not an object, don't touch it
103647d5 79 my $info = $self->column_info($col) || die "No column info for $col";
80 return $value unless exists $info->{_inflate_info};
81 my $deflate = $info->{_inflate_info}{deflate};
82 die "No deflator for $col" unless defined $deflate;
0e5c2582 83 return $deflate->($value, $self);
84}
85
86sub get_inflated_column {
87 my ($self, $col) = @_;
88 $self->throw("$col is not an inflated column") unless
103647d5 89 exists $self->column_info($col)->{_inflate_info};
4a07648a 90
0e5c2582 91 return $self->{_inflated_column}{$col}
92 if exists $self->{_inflated_column}{$col};
0e5c2582 93 return $self->{_inflated_column}{$col} =
4a07648a 94 $self->_inflated_column($col, $self->get_column($col));
0e5c2582 95}
96
97sub set_inflated_column {
98 my ($self, $col, @rest) = @_;
47bd0267 99 my $ret = $self->_inflated_column_op('set', $col, @rest);
0e5c2582 100 return $ret;
101}
102
103sub store_inflated_column {
47bd0267 104 my ($self, $col, @rest) = @_;
105 my $ret = $self->_inflated_column_op('store', $col, @rest);
106 return $ret;
107}
108
109sub _inflated_column_op {
110 my ($self, $op, $col, $obj) = @_;
111 my $meth = "${op}_column";
0e5c2582 112 unless (ref $obj) {
113 delete $self->{_inflated_column}{$col};
47bd0267 114 return $self->$meth($col, $obj);
0e5c2582 115 }
4a07648a 116
117 my $deflated = $self->_deflated_column($col, $obj);
9f300b1b 118 # Do this now so we don't store if it's invalid
4a07648a 119
0e5c2582 120 $self->{_inflated_column}{$col} = $obj;
47bd0267 121 $self->$meth($col, $deflated);
0e5c2582 122 return $obj;
123}
124
125sub new {
126 my ($class, $attrs, @rest) = @_;
127 $attrs ||= {};
0e5c2582 128 foreach my $key (keys %$attrs) {
103647d5 129 if (ref $attrs->{$key}
130 && exists $class->column_info($key)->{_inflate_info}) {
484c9dda 131 $attrs->{$key} = $class->_deflated_column($key, $attrs->{$key});
0e5c2582 132 }
133 }
147dd158 134 return $class->next::method($attrs, @rest);
0e5c2582 135}
136
bcae85db 137=head1 SEE ALSO
138
139=over 4
140
141=item L<DBIx::Class::Core> - This component is loaded as part of the
142 "core" L<DBIx::Class> components; generally there is no need to
143 load it directly
144
145=back
146
147=head1 AUTHOR
148
149Matt S. Trout <mst@shadowcatsystems.co.uk>
150
151=head1 CONTRIBUTORS
152
153Daniel Westermann-Clark <danieltwc@cpan.org> (documentation)
154
155=head1 LICENSE
156
157You may distribute this code under the same terms as Perl itself.
158
159=cut
160
0e5c2582 1611;