File Coverage

blib/lib/WWW/Session/Storage/MySQL.pm
Criterion Covered Total %
statement 9 48 18.7
branch 0 10 0.0
condition 0 6 0.0
subroutine 3 9 33.3
pod 4 4 100.0
total 16 77 20.7


line stmt bran cond sub pod time code
1             package WWW::Session::Storage::MySQL;
2              
3 1     1   738 use 5.006;
  1         2  
  1         32  
4 1     1   4 use strict;
  1         1  
  1         23  
5 1     1   4 use warnings;
  1         11  
  1         477  
6              
7             =head1 NAME
8              
9             WWW::Session::Storage::MySQL - MySQL storage for WWW::Session
10              
11             =head1 DESCRIPTION
12              
13             MySQL backend for WWW:Session
14              
15             =head1 VERSION
16              
17             Version 0.12
18              
19             =cut
20              
21             our $VERSION = '0.12';
22              
23             #Internal variable that controls the expired session cleanup process
24             #We do a cleanup not faster than every 10 minutes, when we try and retrieve
25             my $last_cleanup = 0;
26              
27              
28             =head1 SYNOPSIS
29              
30             This module is used for storring serialized WWW::Session objects in MySQL
31              
32             Usage :
33              
34             use WWW::Session::Storage::MySQL;
35              
36             my $storage = WWW::Session::Storage::MySQL->new({
37             dbh => $dbh,
38             table => 'sessions',
39             fields => {
40             sid => 'session_id',
41             expires => 'expires',
42             data => 'data'
43             }
44             });
45             ...
46            
47             $storage->save($session_id,$expires,$serialized_data);
48            
49             my $serialized_data = $storage->retrive($session_id);
50              
51              
52             The "fields" hasref contains the mapping of session internal data to the column names from MySQL.
53             The keys are the session fields ("sid","expires" and "data") and must all be present.
54              
55             The MySQL types of the columns should be :
56              
57             =over 4
58              
59             =item * sid => varchar(32)
60              
61             =item * expires => DATETIME or TIMESTAMP
62              
63             =item * data => text
64              
65             =back
66              
67             =head1 SUBROUTINES/METHODS
68              
69             =head2 new
70              
71             Creates a new WWW::Session::Storage::MySQL object
72              
73             This method accepts only one argument, a hashref that must contain the fallowing data:
74              
75             =over 4
76              
77             =item * dbh Database handle
78              
79             =item * table The name of the table where the sessions will be stored
80              
81             =item * fields A hash ref containing the falowing keys
82              
83             =over 8
84              
85             =item * sid The same of the database field which will store the session id
86              
87             =item * expires The same of the database field which will store the expiration time
88              
89             =item * data The name of the field where the session data will be stored
90              
91             =back
92              
93             =back
94              
95             =cut
96              
97             sub new {
98 0     0 1   my ($class,$params) = @_;
99            
100 0           my $self = {
101             dbh => $params->{dbh},
102             table => $params->{table},
103             fields => $params->{fields},
104             };
105            
106 0           bless $self,$class;
107            
108 0           $self->_check_table_structure();
109            
110 0           return $self;
111             }
112              
113             =head2 save
114              
115             Stores the given information into the database
116              
117             =cut
118             sub save {
119 0     0 1   my ($self,$sid,$expires,$string) = @_;
120              
121 0 0         $expires = 60*60*24*365*20 if $expires == -1;
122              
123 0           my $query = sprintf('INSERT INTO %s SET %s=?, %s=?,%s=FROM_UNIXTIME(?) ON DUPLICATE KEY UPDATE %s=?, %s=FROM_UNIXTIME(?)',
124             $self->{table},
125 0           @{$self->{fields}}{qw(sid data expires)},
126 0           @{$self->{fields}}{qw(data expires)}
127             );
128              
129 0           my $sth = $self->{dbh}->prepare($query);
130              
131 0           my $rv = $sth->execute($sid,$string,time() + $expires, $string,time() + $expires);
132            
133 0           return $rv;
134             }
135              
136             =head2 retrieve
137              
138             Retrieves the informations for a session, verifies that it's not expired and returns
139             the string containing the serialized data
140              
141             =cut
142             sub retrieve {
143 0     0 1   my ($self,$sid) = @_;
144              
145 0 0         if ( $last_cleanup + 600 < time() ) {
146 0           $last_cleanup = time();
147 0           my $del_sth = $self->{dbh}->prepare(sprintf("DELETE FROM %s WHERE %s < NOW()",$self->{table},$self->{fields}{expires}));
148 0           $del_sth->execute()
149             }
150            
151 0           my $query = sprintf('SELECT %s as sid,%s as data,UNIX_TIMESTAMP(%s) as expires FROM %s WHERE %s=?',
152 0           @{$self->{fields}}{qw(sid data expires)},
153             $self->{table},
154             $self->{fields}->{sid}
155             );
156              
157 0           my $sth = $self->{dbh}->prepare($query);
158 0           $sth->execute($sid);
159            
160 0           my $info = $sth->fetchrow_hashref();
161            
162 0 0         return undef unless defined $info;
163            
164 0 0         if ( $info->{expires} < time() ) {
165 0           $self->delete($sid);
166 0           return undef;
167             }
168            
169 0           return $info->{data};
170              
171             }
172              
173             =head2 delete
174              
175             Completely removes the session data for the given session id
176              
177             =cut
178             sub delete {
179 0     0 1   my ($self,$sid) = @_;
180              
181 0           my $query = sprintf('DELETE FROM %s WHERE %s=?',
182             $self->{table},
183             $self->{fields}->{sid}
184             );
185              
186 0           my $sth = $self->{dbh}->prepare($query);
187 0           my $rv = $sth->execute($sid);
188              
189 0           return $rv;
190             }
191              
192             =head1 Private methods
193              
194             =head2 _determine_expires_type
195              
196             Tries to determine if the expires field is UnixTimestamp or DateTime
197              
198             =cut
199             sub _check_table_structure {
200 0     0     my $self = shift;
201            
202 0           my $sth = $self->{dbh}->prepare("DESCRIBE ".$self->{table});
203 0           $sth->execute();
204            
205 0           my $table_fields = $sth->fetchall_hashref('Field');
206            
207 0 0 0       die "The table structure doesn't match the field names you specified!"
      0        
208             unless exists $table_fields->{$self->{fields}->{sid}} &&
209             exists $table_fields->{$self->{fields}->{expires}} &&
210             exists $table_fields->{$self->{fields}->{data}};
211             }
212              
213             =head2 _reset_last_cleanup
214              
215             Resets the last DB cleanup timer, forcing all expired sessions to be removed when the next session is retrieved
216              
217             =cut
218             sub _reset_last_cleanup {
219 0     0     $last_cleanup = 0;
220             }
221              
222             =head1 AUTHOR
223              
224             Gligan Calin Horea, C<< >>
225              
226             =head1 BUGS
227              
228             Please report any bugs or feature requests to C, or through
229             the web interface at L. I will be notified, and then you'll
230             automatically be notified of progress on your bug as I make changes.
231              
232              
233              
234              
235             =head1 SUPPORT
236              
237             You can find documentation for this module with the perldoc command.
238              
239             perldoc WWW::Session::Storage::MySQL
240              
241              
242             You can also look for information at:
243              
244             =over 4
245              
246             =item * RT: CPAN's request tracker (report bugs here)
247              
248             L
249              
250             =item * AnnoCPAN: Annotated CPAN documentation
251              
252             L
253              
254             =item * CPAN Ratings
255              
256             L
257              
258             =item * Search CPAN
259              
260             L
261              
262             =back
263              
264              
265             =head1 ACKNOWLEDGEMENTS
266              
267              
268             =head1 LICENSE AND COPYRIGHT
269              
270             Copyright 2012 Gligan Calin Horea.
271              
272             This program is free software; you can redistribute it and/or modify it
273             under the terms of either: the GNU General Public License as published
274             by the Free Software Foundation; or the Artistic License.
275              
276             See http://dev.perl.org/licenses/ for more information.
277              
278              
279             =cut
280              
281             1; # End of WWW::Session::Storage::MySQL