pre-0.02 commit
[catagits/Web-Session.git] / lib / Plack / Session / Store / File.pm
1 package Plack::Session::Store::File;
2 use strict;
3 use warnings;
4
5 our $VERSION   = '0.02';
6 our $AUTHORITY = 'cpan:STEVAN';
7
8 use Storable ();
9
10 use parent 'Plack::Session::Store';
11
12 use Plack::Util::Accessor qw[
13     dir
14     serializer
15     deserializer
16 ];
17
18 sub new {
19     my ($class, %params) = @_;
20
21     $params{'dir'} ||= $ENV{TMPDIR} || '/tmp';
22
23     die "Storage directory (" . $params{'dir'} . ") is not writeable"
24         unless -w $params{'dir'};
25
26     $params{'serializer'}   ||= sub { Storable::nstore( @_ ) };
27     $params{'deserializer'} ||= sub { Storable::retrieve( @_ ) };
28
29     bless { %params } => $class;
30 }
31
32 sub fetch {
33     my ($self, $session_id, $key) = @_;
34     my $store = $self->_deserialize( $session_id );
35     return unless exists $store->{ $key };
36     return $store->{ $key };
37 }
38
39 sub store {
40     my ($self, $session_id, $key, $data) = @_;
41     my $store = $self->_deserialize( $session_id );
42     $store->{ $key } = $data;
43     $self->_serialize( $session_id, $store );
44 }
45
46 sub delete {
47     my ($self, $session_id, $key) = @_;
48     my $store = $self->_deserialize( $session_id );
49     return unless exists $store->{ $key };
50     delete $store->{ $key };
51     $self->_serialize( $session_id, $store );
52 }
53
54 sub cleanup {
55     my ($self, $session_id) = @_;
56     unlink $self->_get_session_file_path( $session_id );
57 }
58
59 sub _get_session_file_path {
60     my ($self, $session_id) = @_;
61     $self->dir . '/' . $session_id;
62 }
63
64 sub _serialize {
65     my ($self, $session_id, $value) = @_;
66     my $file_path = $self->_get_session_file_path( $session_id );
67     $self->serializer->( $value, $file_path );
68 }
69
70 sub _deserialize {
71     my ($self, $session_id) = @_;
72     my $file_path = $self->_get_session_file_path( $session_id );
73     $self->_serialize( $session_id, {} ) unless -f $file_path;
74     $self->deserializer->( $file_path );
75 }
76
77 sub dump_session {
78     my ($self, $session_id) = @_;
79     my $file_path = $self->_get_session_file_path( $session_id );
80     return {} unless -f $file_path;
81     $self->deserializer->( $file_path );
82 }
83
84
85 1;
86
87 __END__
88
89 =pod
90
91 =head1 NAME
92
93 Plack::Session::Store::File - Basic file-based session store
94
95 =head1 SYNOPSIS
96
97   use Plack::Builder;
98   use Plack::Middleware::Session;
99   use Plack::Session::Store::File;
100
101   my $app = sub {
102       return [ 200, [ 'Content-Type' => 'text/plain' ], [ 'Hello Foo' ] ];
103   };
104
105   builder {
106       enable 'Session',
107           store => Plack::Session::Store::File->new(
108               dir => '/path/to/sessions'
109           );
110       $app;
111   };
112
113   # with custom serializer/deserializer
114
115   builder {
116       enable 'Session',
117           store => Plack::Session::Store::File->new(
118               dir          => '/path/to/sessions',
119               # YAML takes it's args the opposite order
120               serializer   => sub { YAML::DumpFile( reverse @_ ) },
121               deserializer => sub { YAML::LoadFile( @_ ) },
122           );
123       $app;
124   };
125
126 =head1 DESCRIPTION
127
128 This implements a basic file based storage for session data. By
129 default it will use L<Storable> to serialize and deserialize the
130 data, but this can be configured easily.
131
132 This is a subclass of L<Plack::Session::Store> and implements
133 it's full interface.
134
135 =head1 METHODS
136
137 =over 4
138
139 =item B<new ( %params )>
140
141 The C<%params> can include I<dir>, I<serializer> and I<deserializer>
142 options. It will check to be sure that the I<dir> is writeable for
143 you.
144
145 =item B<dir>
146
147 This is the directory to store the session data files in, if nothing
148 is provided then "/tmp" is used.
149
150 =item B<serializer>
151
152 This is a CORE reference that implements the serialization logic.
153 The CODE ref gets two arguments, the C<$value>, which is a HASH
154 reference to be serialized, and the C<$file_path> to save it to.
155 It is not expected to return anything.
156
157 =item B<deserializer>
158
159 This is a CORE reference that implements the deserialization logic.
160 The CODE ref gets one argument, the C<$file_path> to load the data
161 from. It is expected to return a HASH reference.
162
163 =back
164
165 =head1 BUGS
166
167 All complex software has bugs lurking in it, and this module is no
168 exception. If you find a bug please either email me, or add the bug
169 to cpan-RT.
170
171 =head1 AUTHOR
172
173 Stevan Little E<lt>stevan.little@iinteractive.comE<gt>
174
175 =head1 COPYRIGHT AND LICENSE
176
177 Copyright 2009 Infinity Interactive, Inc.
178
179 L<http://www.iinteractive.com>
180
181 This library is free software; you can redistribute it and/or modify
182 it under the same terms as Perl itself.
183
184 =cut
185