File Coverage

blib/lib/Apache/Session/Browseable/DBI.pm
Criterion Covered Total %
statement 94 94 100.0
branch 22 28 78.5
condition 6 11 54.5
subroutine 11 11 100.0
pod 0 3 0.0
total 133 147 90.4


line stmt bran cond sub pod time code
1             package Apache::Session::Browseable::DBI;
2              
3 3     3   19902 use strict;
  3         5  
  3         109  
4              
5 3     3   16 use DBI;
  3         5  
  3         129  
6 3     3   567 use Apache::Session;
  3         1926  
  3         88  
7 3     3   1318 use Apache::Session::Browseable::_common;
  3         9  
  3         1513  
8              
9             our $VERSION = '1.0';
10             our @ISA = qw(Apache::Session Apache::Session::Browseable::_common);
11              
12             sub searchOn {
13 6     6 0 21332 my $class = shift;
14 6         15 my ( $args, $selectField, $value, @fields ) = @_;
15              
16             # Escape quotes
17 6         14 $value =~ s/'/''/g;
18 6         9 $selectField =~ s/'/''/g;
19 6 100       31 if ( $class->_fieldIsIndexed( $args, $selectField ) ) {
20 4         29 return $class->_query( $args, $selectField, $value,
21             { query => "$selectField=?", values => [$value] }, @fields );
22             }
23             else {
24 2         48 return $class->SUPER::searchOn(@_);
25             }
26             }
27              
28             sub searchOnExpr {
29 2     2 0 3 my $class = shift;
30 2         4 my ( $args, $selectField, $value, @fields ) = @_;
31              
32             # Escape quotes
33 2         5 $value =~ s/'/''/g;
34 2         2 $selectField =~ s/'/''/g;
35 2 100       16 if ( $class->_fieldIsIndexed( $args, $selectField ) ) {
36 1         3 $value =~ s/\*/%/g;
37 1         7 return $class->_query( $args, $selectField, $value,
38             { query => "$selectField like ?", values => [$value] }, @fields );
39             }
40             else {
41 1         13 return $class->SUPER::searchOnExpr(@_);
42             }
43             }
44              
45             sub _query {
46 5     5   13 my ( $class, $args, $selectField, $value, $query, @fields ) = @_;
47 5         9 my %res = ();
48 5 50       21 my $index =
49             ref( $args->{Index} )
50             ? $args->{Index}
51             : [ split /\s+/, $args->{Index} ];
52              
53 5         20 my $dbh = $class->_classDbh($args);
54 5   33     1380 my $table_name = $args->{TableName}
55             || $Apache::Session::Store::DBI::TableName;
56              
57             # Case 1: all requested fields are also indexed
58 5         27 my $indexed = $class->_tabInTab( \@fields, $index );
59 5         6 my $sth;
60 5 100       13 if ($indexed) {
61 1         2 my $fields = join( ',', 'id', map { s/'//g; $_ } @fields );
  2         4  
  2         4  
62 1         9 $sth = $dbh->prepare(
63             "SELECT $fields from $table_name where $query->{query}");
64 1         129 $sth->execute( @{ $query->{values} } );
  1         80  
65 1         8 return $sth->fetchall_hashref('id');
66             }
67              
68             # Case 1: at least one field isn't indexed, decoding is needed
69             else {
70 4         34 $sth =
71             $dbh->prepare(
72             "SELECT id,a_session from $table_name where $query->{query}");
73 4         584 $sth->execute( @{ $query->{values} } );
  4         342  
74 4         78 while ( my @row = $sth->fetchrow_array ) {
75 3     3   20 no strict 'refs';
  3         4  
  3         1024  
76 7         491 my $self = eval "&${class}::populate();";
77 7         24 my $sub = $self->{unserialize};
78 7         27 my $tmp = &$sub( { serialized => $row[1] } );
79 7 100       209 if (@fields) {
80 2         27 $res{ $row[0] }->{$_} = $tmp->{$_} foreach (@fields);
81             }
82             else {
83 5         27 $res{ $row[0] } = $tmp;
84             }
85             }
86             }
87 4         77 return \%res;
88             }
89              
90             sub get_key_from_all_sessions {
91 6     6 0 2079 my $class = shift;
92 6         10 my $args = shift;
93 6         9 my $data = shift;
94              
95 6   33     27 my $table_name = $args->{TableName}
96             || $Apache::Session::Store::DBI::TableName;
97 6         25 my $dbh = $class->_classDbh($args);
98              
99             # Special case if all wanted fields are indexed
100 6 100 100     1520 if ( $data and ref($data) ne 'CODE' ) {
101 2 50       7 $data = [$data] unless ( ref($data) );
102 2 50       13 my $index =
103             ref( $args->{Index} )
104             ? $args->{Index}
105             : [ split /\s+/, $args->{Index} ];
106              
107             # Test if one field isn't indexed
108 2         11 my $indexed = $class->_tabInTab( $data, $index );
109              
110             # OK, all fields are indexed
111 2 100       9 if ($indexed) {
112 2         4 my $sth =
113             $dbh->prepare_cached( 'SELECT id,'
114 1         2 . join( ',', map { s/'/''/g; $_ } @$data )
  2         8  
115             . " from $table_name" );
116 1         154 $sth->execute;
117 1         14 return $sth->fetchall_hashref('id');
118             }
119             }
120 5         45 my $sth = $dbh->prepare_cached("SELECT id,a_session from $table_name");
121 5         718 $sth->execute;
122 5         13 my %res;
123 5         65 while ( my @row = $sth->fetchrow_array ) {
124 3     3   16 no strict 'refs';
  3         4  
  3         766  
125 140         7373 my $self = eval "&${class}::populate();";
126 140         289 my $sub = $self->{unserialize};
127 140         462 my $tmp = &$sub( { serialized => $row[1] } );
128 140 100       3078 if ( ref($data) eq 'CODE' ) {
    100          
129 84         2483 $tmp = &$data( $tmp, $row[0] );
130 84 50       433 $res{ $row[0] } = $tmp if ( defined($tmp) );
131             }
132             elsif ($data) {
133 28 50       60 $data = [$data] unless ( ref($data) );
134 28         271 $res{ $row[0] }->{$_} = $tmp->{$_} foreach (@$data);
135             }
136             else {
137 28         133 $res{ $row[0] } = $tmp;
138             }
139             }
140 5         120 return \%res;
141             }
142              
143             sub _classDbh {
144 11     11   18 my $class = shift;
145 11         14 my $args = shift;
146              
147 11 50       35 my $datasource = $args->{DataSource} or die "No datasource given !";
148 11         18 my $username = $args->{UserName};
149 11         15 my $password = $args->{Password};
150 11   50     70 my $dbh =
151             DBI->connect_cached( $datasource, $username, $password,
152             { RaiseError => 1, AutoCommit => 1 } )
153             || die $DBI::errstr;
154             }
155              
156             1;
157