line endings, tabs, version bump, leave user-supplied values for update()
[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.03';
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 AUTHOR
83
84 =over 4
85
86 =item * Brian Cassidy E<lt>bricas@cpan.orgE<gt>
87
88 =item * Adam Paynter E<lt>adapay@cpan.orgE<gt>
89
90 =back
91
92 =head1 COPYRIGHT AND LICENSE
93
94 Copyright 2006 by Brian Cassidy
95
96 This library is free software; you can redistribute it and/or modify
97 it under the same terms as Perl itself. 
98
99 =cut
100
101 __PACKAGE__->mk_classdata( ctime_columns => [ ] );
102 __PACKAGE__->mk_classdata( mtime_columns => [ ] );
103
104 sub register_column {
105     my( $class, $col, $info ) = @_;
106     $class->next::method( $col, $info );
107     
108     if( my $type = $info->{ epoch } ) {
109         $class->ctime_columns( [ @{ $class->ctime_columns }, $col ] ) if $type eq 'ctime';
110         $class->mtime_columns( [ @{ $class->mtime_columns }, $col ] ) if $type eq 'mtime';
111         
112         $class->inflate_column(
113             $col => {
114                 inflate => sub { DateTime->from_epoch( epoch => shift ) },
115                 deflate => sub { shift->epoch }
116             }
117         );
118     }
119 }
120
121 sub insert {
122     my $self = shift;
123     my $time = time;
124     
125     for my $column ( @{ $self->ctime_columns }, @{ $self->mtime_columns } ) {
126         next if defined $self->get_column( $column );
127         $self->store_column( $column => $time );
128     }
129
130     $self->next::method( @_ );
131 }
132
133 sub update {
134     my $self  = shift;
135     my $time  = time;
136     my %dirty = $self->get_dirty_columns;
137
138     for my $column ( @{ $self->mtime_columns } ) {
139         next if exists $dirty{ $column };
140         $self->set_column( $column => $time );
141     }
142     
143     $self->next::method( @_ );
144 }
145
146 1;