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