File Coverage

blib/lib/Dancer/Session/JSON.pm
Criterion Covered Total %
statement 73 73 100.0
branch 16 24 66.6
condition n/a
subroutine 17 17 100.0
pod 6 6 100.0
total 112 120 93.3


line stmt bran cond sub pod time code
1 1     1   168920 use strict;
  1         1  
  1         21  
2 1     1   3 use warnings;
  1         2  
  1         39  
3             package Dancer::Session::JSON;
4             # ABSTRACT: JSON session backend for Dancer
5             $Dancer::Session::JSON::VERSION = '0.002';
6 1     1   3 use Carp;
  1         1  
  1         40  
7 1     1   3 use base 'Dancer::Session::Abstract';
  1         5  
  1         395  
8              
9 1     1   1171 use JSON;
  1         7768  
  1         3  
10 1     1   85 use Fcntl ':flock';
  1         1  
  1         83  
11 1     1   5 use Dancer::Logger;
  1         1  
  1         14  
12 1     1   3 use Dancer::ModuleLoader;
  1         1  
  1         15  
13 1     1   3 use Dancer::Config 'setting';
  1         1  
  1         33  
14 1     1   8 use Dancer::FileUtils qw(path set_file_mode);
  1         1  
  1         415  
15              
16             # static
17              
18             my %session_dir_initialized;
19             my $json = JSON->new;
20              
21             sub init {
22 3     3 1 16 my $self = shift;
23              
24 3         10 $self->SUPER::init(@_);
25              
26             # default value for session_dir
27 3 100       341 defined setting('session_dir')
28             or setting( session_dir => path( setting('appdir'), 'sessions' ) );
29              
30 3         61 my $session_dir = setting('session_dir');
31 3 100       18 if ( ! exists $session_dir_initialized{$session_dir} ) {
32 2         3 $session_dir_initialized{$session_dir} = 1;
33              
34             # make sure session_dir exists
35 2 50       28 if ( ! -d $session_dir ) {
36 2 50       71 mkdir $session_dir
37             or croak "session_dir $session_dir cannot be created";
38             }
39              
40 2         9 Dancer::Logger::core("session_dir: $session_dir");
41             }
42             }
43              
44             # create a new session and return the newborn object
45             # representing that session
46             sub create {
47 3     3 1 1322 my ($class) = @_;
48              
49 3         16 my $self = Dancer::Session::JSON->new;
50 3         15 $self->flush;
51              
52 2         3 return $self;
53             }
54              
55             # deletes the dir cache
56             sub reset {
57 1     1 1 418 my ($class) = @_;
58 1         3 %session_dir_initialized = ();
59             }
60              
61             # Return the session object corresponding to the given id
62             sub retrieve {
63 6     6 1 2451 my $class = shift;
64 6         6 my $id = shift;
65 6         7 my $session_file = _json_file($id);
66              
67 6 100       225 return unless -f $session_file;
68              
69 4 50       87 open my $fh, '+<', $session_file or die "Can't open '$session_file': $!\n";
70 4 50       19 flock $fh, LOCK_EX or die "Can't lock file '$session_file': $!\n";
71 4         3 my $json_data = do { local $/ = undef; <$fh>; };
  4         12  
  4         38  
72 4         23 my $content = $json->decode($json_data);
73 4 50       27 close $fh or die "Can't close '$session_file': $!\n";
74              
75 4         24 return bless $content => 'Dancer::Session::JSON';
76             }
77              
78             # instance
79             sub _json_file {
80 12     12   28 my $id = shift;
81 12         22 return path( setting('session_dir'), "$id.json" );
82             }
83              
84             sub destroy {
85 1     1 1 527 my ($self) = @_;
86              
87 1         3 my $file = _json_file( $self->id );
88 1         27 Dancer::Logger::core("trying to remove session file: $file");
89              
90 1 50       68 -f $file and unlink $file;
91             }
92              
93             sub flush {
94 4     4 1 394 my $self = shift;
95 4         11 my $session_file = _json_file( $self->id );
96              
97 4 100       271 open my $fh, '>', $session_file or die "Can't open '$session_file': $!\n";
98 3 50       14 flock $fh, LOCK_EX or die "Can't lock file '$session_file': $!\n";
99 3         9 set_file_mode($fh);
100 3         19 print {$fh} $json->allow_blessed->convert_blessed->encode(
101 3         246 +{ %{$self} }
  3         36  
102             );
103              
104 3 50       122 close $fh or die "Can't close '$session_file': $!\n";
105              
106 3         10 return $self;
107             }
108              
109             1;
110              
111             __END__