1 package CGI::Session::Driver::postgresql;
3 # $Id: postgresql.pm 351 2006-11-24 14:16:50Z markstos $
5 # CGI::Session::Driver::postgresql - PostgreSQL driver for CGI::Session
7 # Copyright (C) 2002 Cosimo Streppone, cosimo@cpan.org
8 # This module is based on CGI::Session::Driver::mysql module
9 # by Sherzod Ruzmetov, original author of CGI::Session modules
10 # and CGI::Session::Driver::mysql driver.
15 use CGI::Session::Driver::DBI;
16 use DBD::Pg qw(PG_BYTEA PG_TEXT);
18 $CGI::Session::Driver::postgresql::VERSION = '4.20';
19 @CGI::Session::Driver::postgresql::ISA = qw( CGI::Session::Driver::DBI );
24 my $ret = $self->SUPER::init(@_);
26 # Translate external ColumnType into internal value. See POD for details.
27 $self->{PgColumnType} ||= (defined $self->{ColumnType} and (lc $self->{ColumnType} eq 'binary'))
37 my ($sid, $datastr) = @_;
38 croak "store(): usage error" unless $sid && $datastr;
40 my $dbh = $self->{Handle};
41 my $type = $self->{PgColumnType};
43 if ($type == PG_TEXT && $datastr =~ tr/\x00//) {
44 croak "Unallowed characters used in session data. Please see CGI::Session::Driver::postgresql ".
45 "for more information about null characters in text columns.";
48 local $dbh->{RaiseError} = 1;
50 # There is a race condition were two clients could run this code concurrently,
51 # and both end up trying to insert. That's why we check for "duplicate" below
52 my $sth = $dbh->prepare(
53 "INSERT INTO " . $self->table_name . " (a_session,id) SELECT ?, ?
54 WHERE NOT EXISTS (SELECT 1 FROM " . $self->table_name . " WHERE id=? LIMIT 1)");
56 $sth->bind_param(1,$datastr,{ pg_type => $type });
57 $sth->bind_param(2, $sid);
58 $sth->bind_param(3, $sid); # in the SELECT statement
60 eval { $rv = $sth->execute(); };
61 if ( $rv eq '0E0' or (defined $@ and $@ =~ m/duplicate/i) ) {
62 my $sth = $dbh->prepare("UPDATE " . $self->table_name . " SET a_session=? WHERE id=?");
63 $sth->bind_param(1,$datastr,{ pg_type => $type });
64 $sth->bind_param(2,$sid);
68 # Nothing. Our insert has already happened
72 return $self->set_error( "store(): failed with message: $@ " . $dbh->errstr );
89 CGI::Session::Driver::postgresql - PostgreSQL driver for CGI::Session
94 $session = new CGI::Session("driver:PostgreSQL", undef, {Handle=>$dbh});
98 CGI::Session::PostgreSQL is a L<CGI::Session|CGI::Session> driver to store session data in a PostgreSQL table.
102 Before you can use any DBI-based session drivers you need to make sure compatible database table is created for CGI::Session to work with. Following command will produce minimal requirements in most SQL databases:
104 CREATE TABLE sessions (
105 id CHAR(32) NOT NULL PRIMARY KEY,
106 a_session BYTEA NOT NULL
109 and within your code use:
112 $session = new CGI::Session("driver:PostgreSQL", undef, {Handle=>$dbh, ColumnType=>"binary"});
114 Please note the I<ColumnType> argument. PostgreSQL's text type has problems when trying to hold a null character. (Known as C<"\0"> in Perl, not to be confused with SQL I<NULL>). If you know there is no chance of ever having a null character in the serialized data, you can leave off the I<ColumnType> attribute. Using a I<BYTEA> column type and C<< ColumnType => 'binary' >> is recommended when using L<Storable|CGI::Session::Serialize::storable> as the serializer or if there's any possibility that a null value will appear in any of the serialized data.
116 For more details see L<CGI::Session::Driver::DBI|CGI::Session::Driver::DBI>, parent class.
118 Also see L<sqlite driver|CGI::Session::Driver::sqlite>, which exercises different method for dealing with binary data.
122 Copyright (C) 2002 Cosimo Streppone. All rights reserved. This library is free software and can be modified and distributed under the same terms as Perl itself.
126 Cosimo Streppone <cosimo@cpan.org>, heavily based on the CGI::Session::MySQL driver by Sherzod Ruzmetov, original author of CGI::Session.
128 Matt LeBlanc contributed significant updates for the 4.0 release.
132 For additional support and licensing see L<CGI::Session|CGI::Session>