f0f74b3c4c88bb1d1ff9aa2299f8ba41645334b0
[dbsrgits/DBIx-Class-DateTime-Epoch.git] / lib / DBIx / Class / DateTime / Epoch.pm
1 package DBIx::Class::DateTime::Epoch;
2
3 use strict;
4 use warnings;
5
6 our $VERSION = '0.04';
7
8 use base qw( DBIx::Class );
9
10 use DateTime;
11
12 =head1 NAME
13
14 DBIx::Class::DateTime::Epoch - Automatic inflation/deflation of epoch-based DateTime objects for DBIx::Class
15
16 =head1 SYNOPSIS
17
18     package foo;
19     
20     use base qw( DBIx::Class );
21     
22     __PACKAGE__->load_components( qw( DateTime::Epoch Core ) );
23     __PACKAGE__->add_columns(
24         name => {
25             data_type => 'varchar',
26             size      => 10
27         },
28         bar => {
29             data_type => 'bigint',
30             epoch     => 1
31         },
32         creation_time => {
33             data_type => 'bigint',
34             epoch     => 'ctime'
35         },
36         modification_time => {
37             data_type => 'bigint',
38             epoch     => 'mtime'
39         }
40     );
41
42 =head1 DESCRIPTION
43
44 This module automatically inflates/deflates DateTime objects
45 corresponding to applicable columns. Columns may also be
46 defined to specify their nature, such as columns representing a
47 creation time (set at time of insertion) or a modification time
48 (set at time of every update).
49
50 =head1 METHODS
51
52 =head2 register_column
53
54 This method will automatically add inflation and deflation rules
55 to a column if an epoch value has been set in the column's definition.
56 If the epoch value is 'ctime' (creation time) or 'mtime'
57 (modification time), it will be registered as such for later
58 use by the insert and the update methods.
59
60 =head2 insert
61
62 This method will set the value of all registered creation time
63 columns to the current time. No changes will be made to a column
64 whose value has already been set.
65
66 =head2 update
67
68 This method will set the value of all registered modification time
69 columns to the current time. This will overwrite a column's value,
70 even if it has been already set.
71
72 =head1 SEE ALSO
73
74 =over 4
75
76 =item * DateTime
77
78 =item * DBIx::Class
79
80 =back
81
82 =head1 AUTHORS
83
84 Brian Cassidy E<lt>bricas@cpan.orgE<gt>
85
86 Adam Paynter E<lt>adapay@cpan.orgE<gt>
87
88 =head1 COPYRIGHT AND LICENSE
89
90 Copyright 2007 by Brian Cassidy
91
92 This library is free software; you can redistribute it and/or modify
93 it under the same terms as Perl itself. 
94
95 =cut
96
97 __PACKAGE__->mk_classdata( ctime_columns => [] );
98 __PACKAGE__->mk_classdata( mtime_columns => [] );
99
100 sub register_column {
101     my ( $class, $col, $info ) = @_;
102     $class->next::method( $col, $info );
103
104     if ( my $type = $info->{ epoch } ) {
105         $class->ctime_columns( [ @{ $class->ctime_columns }, $col ] )
106             if $type eq 'ctime';
107         $class->mtime_columns( [ @{ $class->mtime_columns }, $col ] )
108             if $type eq 'mtime';
109
110         $class->inflate_column(
111             $col => {
112                 inflate => sub { DateTime->from_epoch( epoch => shift ) },
113                 deflate => sub { shift->epoch }
114             }
115         );
116     }
117 }
118
119 sub insert {
120     my $self = shift;
121     my $time = time;
122
123     for my $column ( @{ $self->ctime_columns }, @{ $self->mtime_columns } ) {
124         next if defined $self->get_column( $column );
125         $self->store_column( $column => $time );
126     }
127
128     $self->next::method( @_ );
129 }
130
131 sub update {
132     my $self  = shift;
133     my $time  = time;
134     my %dirty = $self->get_dirty_columns;
135
136     for my $column ( @{ $self->mtime_columns } ) {
137         next if exists $dirty{ $column };
138         $self->set_column( $column => $time );
139     }
140
141     $self->next::method( @_ );
142 }
143
144 1;