root/lang/perl/DBIx-Class-DateTimeColumns/trunk/lib/DBIx/Class/DateTimeColumns.pm @ 16128

Revision 16128, 6.3 kB (checked in by lyokato, 5 years ago)

lang/perl/DBix-Class-DateTimeColumns?: initial-release onto coderepos

Line 
1package DBIx::Class::DateTimeColumns;
2use strict;
3use warnings;
4
5use base 'DBIx::Class';
6use Scalar::Util qw/blessed/;
7
8our $VERSION = "0.01";
9
10__PACKAGE__->mk_classdata( _datetime_class   => 'DateTime' );
11__PACKAGE__->mk_classdata( datetime_timezone => 'local'    );
12__PACKAGE__->mk_classdata( _auto_create_datetime_columns => [qw/created_on created_at/] );
13__PACKAGE__->mk_classdata( _auto_update_datetime_columns => [qw/updated_on updated_at/] );
14
15=head1 NAME
16
17DBIx::Class::DateTimeColumns - datetime handler on columns
18
19=head1 SYNOPSIS
20
21  package Artist;
22  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
23  __PACKAGE__->datetime_columns(qw/created_on updated_on/);
24
25  my $artist = Artist->find($id);
26  $artist->created_on->ymd;
27  $artist->updated_on->hms;
28
29=head1 DESCRIPTION
30
31datetime handlers on columns
32
33=head1 METHODS
34
35=head2 auto_create_datetime_columns
36
37special name columns(by default, they're *created_on* and *created_at*)
38are set automatically when you insert a new record into database.
39
40  package Artist;
41  use base 'DBIx::Class';
42  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
43  __PACKAGE__->datetime_columns(qw/created_on saved_on/);
44
45  my $artist = Artist->new;
46  $artist->set_columns({
47    name => 'John',
48    age  => 30,
49  });
50  $artist->insert;
51  # then automatically set current datetime for *created_on*
52
53if you wanna change the special columns' name, of course, you can.
54
55  package Artist;
56  use base 'DBIx::Class';
57  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
58  __PACKAGE__->auto_create_datetime_columns(qw/saved_on/);
59  __PACKAGE__->datetime_columns(qw/created_on saved_on/);
60
61  my $artist = Artist->new;
62  $artist->set_columns({
63    name => 'John',
64    age  => 30,
65  });
66  $artist->insert;
67  # then automatically set current datetime for *saved_on*
68
69=cut
70
71sub auto_create_datetime_columns {
72  my $self = shift;
73  for (@_) {
74    $self->throw_exception("column $_ doesn't exist")
75      unless $self->has_column($_);
76  }
77  $self->_auto_create_datetime_columns(\@_) if @_;
78  $self->_auto_create_datetime_columns;
79}
80
81=head2 auto_update_datetime_columns
82
83special name columns(by default, they're *updated_on* and *updated_at*)
84are set automatically when you update records.
85
86  package Artist;
87  use base 'DBIx::Class';
88  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
89  __PACKAGE__->datetime_columns(qw/updated_on saved_on/);
90
91  my $artist = Artist->find($id);
92  $artist->set_columns({
93    name => 'John',
94    age  => 30,
95  });
96  $artist->update;
97  # then automatically set current datetime for *updated_on*
98
99if you wanna change the special columns' name, of course, you can.
100
101  package Artist;
102  use base 'DBIx::Class';
103  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
104  __PACKAGE__->auto_update_datetime_columns(qw/saved_on/);
105  __PACKAGE__->datetime_columns(qw/updated_on saved_on/);
106
107  my $artist = Artist->find($id);
108  $artist->set_columns({
109    name => 'John',
110    age  => 30,
111  });
112  $artist->update;
113  # then automatically set current datetime for *saved_on*
114
115=cut
116
117sub auto_update_datetime_columns {
118  my $self = shift;
119  for (@_) {
120    $self->throw_exception("column $_ doesn't exist")
121      unless $self->has_column($_);
122  }
123  $self->_auto_update_datetime_columns(\@_) if @_;
124  $self->_auto_update_datetime_columns;
125}
126
127=head2 datetime_class
128
129You can set your own class extends DateTime.
130
131  package Artist;
132  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
133  __PACKAGE__->datetime_class('DateTime::SubClass');
134
135=head2 datetime_timezone
136
137You can set default timezone for datetime columns.
138'local' is set by default.
139
140  package Artist;
141  __PACKAGE__->load_components(qw/DateTimeColumns::MySQL Core/);
142  __PACKAGE__->datetime_timezone('Asia/Tokyo');
143
144=cut
145
146sub datetime_class {
147  my ($self, $class) = @_;
148  if ($class) {
149    if (!eval "require $class") {
150      $self->throw_exception("$class could not be loaded: $@");
151    } elsif (!$class->isa('DateTime')) {
152      $self->throw_exception("$class is not DateTime or it's subclass");
153    } else {
154      $self->_datetime_class($class);
155    }
156  }
157  return $self->_datetime_class;
158}
159
160=head2 insert
161
162=cut
163
164sub insert {
165  my $self = shift;
166  for my $column (@{$self->auto_create_datetime_columns},
167    @{$self->auto_update_datetime_columns}) {
168    if ( $self->has_column($column)
169      && $self->column_info($column)->{_inflate_info}) {
170      $self->store_column($column, $self->get_current_datetime);
171    }
172  }
173  $self->next::method(@_);
174}
175
176=head2 update
177
178=cut
179
180sub update {
181  my $self = shift;
182  for my $column (@{$self->auto_update_datetime_columns}) {
183    warn($column);
184    if ( $self->has_column($column)
185      && $self->column_info($column)->{_inflate_info}) {
186      my $ret = $self->store_column($column, $self->get_current_datetime);
187      $self->{_dirty_columns}{$column} = 1;
188    }
189  }
190  $self->next::method(@_);
191}
192
193=head2 get_current_datetime
194
195=cut
196
197sub get_current_datetime {
198  my $self = shift;
199  return $self->datetime_class->now(time_zone => $self->datetime_timezone);
200}
201
202=head2 datetime_columns(@columns)
203
204=head2 date_columns(@columns)
205
206=head2 timestamp_columns(@columns)
207
208=head2 timestamptz_columns(@columns)
209
210=head2 time_columns(@columns)
211
212=head2 timetz_columns(@columns)
213
214=head2 duration_columns(@columns)
215
216=head2 interval_columns(@columns)
217
218=head2 epoch_columns(@columns)
219
220=cut
221
222# define these methods in subclass
223sub datetime_columns    { die "virtual method!" }
224sub date_columns        { die "virtual method!" }
225sub timestamp_columns   { die "virtual method!" }
226sub timestamptz_columns { die "virtual method!" }
227sub time_columns        { die "virtual method!" }
228sub timetz_columns      { die "virtual method!" }
229sub duration_columns    { die "virtual method!" }
230sub interval_columns    { die "virtual method!" }
231
232sub epoch_columns {
233  my ($self, @columns) = @_;
234  for my $column (@columns) {
235    $self->inflate_column($column, {
236      inflate => sub {
237        my $data = shift;
238        return $data if blessed($data) && $data->isa('DateTime');
239        $self->datetime_class->from_epoch(
240          epoch     => $data,
241          time_zone => $self->datetime_timezone,
242        );
243      },
244      deflate => sub { shift->epoch },
245    });
246  }
247}
248
249=head1 AUTHOR
250
251Lyo Kato, C<lyo.kato@gmail.com>
252
253=head1 COPYRIGHT AND LICENSE
254
255This library is free software; you can redistribute it and/or modify
256it under the same terms as Perl itself.
257
258=cut
259
2601;
261
Note: See TracBrowser for help on using the browser.