1############################################################################# 2# 3# Apache::Session::Store::Postgres 4# Implements session object storage via Postgres 5# Copyright(c) 1998, 1999, 2000 Jeffrey William Baker (jwbaker@acm.org) 6# Distribute under the Perl License 7# 8############################################################################ 9 10package Apache::Session::Store::Postgres; 11 12use strict; 13 14use DBI; 15use Apache::Session::Store::DBI; 16 17use vars qw(@ISA $VERSION); 18 19@ISA = qw(Apache::Session::Store::DBI); 20$VERSION = '1.03'; 21 22$Apache::Session::Store::Postgres::DataSource = undef; 23$Apache::Session::Store::Postgres::UserName = undef; 24$Apache::Session::Store::Postgres::Password = undef; 25 26sub connection { 27 my $self = shift; 28 my $session = shift; 29 30 return if (defined $self->{dbh}); 31 32 $self->{'table_name'} = $session->{args}->{TableName} || $Apache::Session::Store::DBI::TableName; 33 34 if (exists $session->{args}->{Handle}) { 35 $self->{dbh} = $session->{args}->{Handle}; 36 $self->{commit} = $session->{args}->{Commit}; 37 return; 38 } 39 40 my $datasource = $session->{args}->{DataSource} || 41 $Apache::Session::Store::Postgres::DataSource; 42 my $username = $session->{args}->{UserName} || 43 $Apache::Session::Store::Postgres::UserName; 44 my $password = $session->{args}->{Password} || 45 $Apache::Session::Store::Postgres::Password; 46 47 $self->{dbh} = DBI->connect( 48 $datasource, 49 $username, 50 $password, 51 { RaiseError => 1, AutoCommit => 0 } 52 ) || die $DBI::errstr; 53 54 55 #If we open the connection, we close the connection 56 $self->{disconnect} = 1; 57 58 #the programmer has to tell us what commit policy to use 59 $self->{commit} = $session->{args}->{Commit}; 60} 61 62sub materialize { 63 my $self = shift; 64 my $session = shift; 65 66 $self->connection($session); 67 68 local $self->{dbh}->{RaiseError} = 1; 69 70 if (!defined $self->{materialize_sth}) { 71 $self->{materialize_sth} = 72 $self->{dbh}->prepare_cached(qq{ 73 SELECT a_session FROM $self->{'table_name'} WHERE id = ? FOR UPDATE}); 74 } 75 76 $self->{materialize_sth}->bind_param(1, $session->{data}->{_session_id}); 77 78 $self->{materialize_sth}->execute; 79 80 my $results = $self->{materialize_sth}->fetchrow_arrayref; 81 82 if (!(defined $results)) { 83 $self->{materialize_sth}->finish; 84 die "Object does not exist in the data store"; 85 } 86 87 $self->{materialize_sth}->finish; 88 89 $session->{serialized} = $results->[0]; 90} 91 92sub DESTROY { 93 my $self = shift; 94 95 if ($self->{commit}) { 96 $self->{dbh}->commit; 97 } 98 99 if ($self->{disconnect}) { 100 $self->{dbh}->disconnect; 101 } 102} 103 1041; 105 106=pod 107 108=head1 NAME 109 110Apache::Session::Store::Postgres - Store persistent data in a Postgres database 111 112=head1 SYNOPSIS 113 114 use Apache::Session::Store::Postgres; 115 116 my $store = new Apache::Session::Store::Postgres; 117 118 $store->insert($ref); 119 $store->update($ref); 120 $store->materialize($ref); 121 $store->remove($ref); 122 123=head1 DESCRIPTION 124 125Apache::Session::Store::Postgres fulfills the storage interface of 126Apache::Session. Session data is stored in a Postgres database. 127 128=head1 SCHEMA 129 130To use this module, you will need at least these columns in a table 131called 'sessions', or another name if you supply the TableName parameter. 132 133 id char(32) # or however long your session IDs are. 134 a_session text # This has an ~8 KB limit :( 135 136To create this schema, you can execute this command using the psql program: 137 138 CREATE TABLE sessions ( 139 id char(32) not null primary key, 140 a_session text 141 ); 142 143If you use some other command, ensure that there is a unique index on the 144table's id column. 145 146=head1 CONFIGURATION 147 148The module must know what datasource, username, and password to use when 149connecting to the database. These values can be set using the options hash 150(see Apache::Session documentation). The options are: 151 152=over 4 153 154=item DataSource 155 156=item UserName 157 158=item Password 159 160=item Handle 161 162=item TableName 163 164=back 165 166Example: 167 168 tie %hash, 'Apache::Session::Postgres', $id, { 169 DataSource => 'dbi:Pg:dbname=database', 170 UserName => 'database_user', 171 Password => 'K00l' 172 }; 173 174Instead, you may pass in an already-opened DBI handle to your database. 175 176 tie %hash, 'Apache::Session::Postgres', $id, { 177 Handle => $dbh 178 }; 179 180=head1 AUTHOR 181 182This modules was written by Jeffrey William Baker <jwbaker@acm.org> 183 184A fix for the commit policy was contributed by Michael Schout <mschout@gkg.net> 185 186=head1 SEE ALSO 187 188L<Apache::Session>, L<Apache::Session::Store::DBI> 189