home *** CD-ROM | disk | FTP | other *** search
- # CGI::Session::PostgreSQL - PostgreSQL driver for CGI::Session
- #
- # Copyright (C) 2001-2002 Sherzod Ruzmetov, sherzodr@cpan.org
- #
- # Copyright (C) 2002 Cosimo Streppone, cosimo@cpan.org
- # This module is based on CGI::Session::MySql module
- # by Sherzod Ruzmetov, original author of CGI::Session modules
- # and CGI::Session::MySQL driver.
- #
- # 2002/12/08 cosimo@cpan.org
- # Initial release
- # 2003/03/01 cosimo@cpan.org
- # Added `FOR UPDATE' sql clauses to enable database row lock management
- #
- # $Id: PostgreSQL.pm,v 1.2 2003/03/01 12:46:55 cosimo Exp $
-
- package CGI::Session::PostgreSQL;
-
- use strict;
- # Inheriting necessary functionalities from the
- # following libraries. Do not change it unless you know
- # what you are doing
- use base qw(
- CGI::Session
- CGI::Session::ID::MD5
- CGI::Session::Serialize::Default
- );
-
-
- # driver specific libraries should go below
-
- use vars qw($VERSION $TABLE_NAME);
-
- ($VERSION) = '$Revision: 1.2 $' =~ m/Revision:\s*(\S+)/;
- $TABLE_NAME = 'sessions';
-
- ########################
- # Driver methods follow
- ########################
-
-
- # stores the serialized data. Returns 1 for sucess, undef otherwise
- sub store {
-
- my ($self, $sid, $options, $data) = @_;
- my $dbh = $self->PostgreSQL_dbh($options);
- my $db_data;
-
- eval {
-
- ($db_data) = $dbh->selectrow_array(
- ' SELECT a_session FROM '.$TABLE_NAME.
- ' WHERE id = '.$dbh->quote($sid).' FOR UPDATE'
- );
-
- };
-
- if( $@ ) {
- $self->error("Couldn't acquire data on id '$sid'");
- return undef;
- }
-
- eval {
-
- if( $db_data ) {
-
- #warn('do update sid='.$sid.' data='.$self->freeze($data));
-
- $dbh->do(
- ' UPDATE '.$TABLE_NAME.
- ' SET a_session='.$dbh->quote($self->freeze($data)).
- ' WHERE id='.$dbh->quote($sid)
- );
-
- } else {
-
- #warn('do insert sid='.$sid.' data='.$self->freeze($data));
-
- $dbh->do(
- 'INSERT INTO '.$TABLE_NAME.' (id,a_session) '.
- 'VALUES ('.$dbh->quote($sid).', '.$dbh->quote($self->freeze($data)).')'
- );
-
- }
-
- };
-
- if( $@ ) {
- $self->error("Error in session update on id '$sid'. $@");
- warn("Error in session update on id '$sid'. $@");
- return undef;
- }
-
- return 1;
- }
-
-
-
- # retrieves the serialized data and deserializes it
- sub retrieve {
- my ($self, $sid, $options) = @_;
-
- # after you get the data, deserialize it using
- # $self->thaw(), and return it
- my $dbh = $self->PostgreSQL_dbh($options);
- my $data;
- eval {
- $data = $dbh->selectrow_array(
- ' SELECT a_session FROM '.$TABLE_NAME.
- ' WHERE id = '.$dbh->quote($sid)
- );
- };
- if( $@ ) {
- $self->error("Couldn't acquire data on id '$sid'");
- return undef;
- }
- return $self->thaw($data);
- }
-
-
- # removes the given data and all the disk space associated with it
- sub remove {
- my ($self, $sid, $options) = @_;
-
- my $dbh = $self->PostgreSQL_dbh($options);
- my $data;
- eval {
- $data = $dbh->selectrow_array(
- ' SELECT a_session FROM '.$TABLE_NAME.
- ' WHERE id = '.$dbh->quote($sid).' FOR UPDATE'
- );
- };
- if( $@ ) {
- $self->error("Couldn't acquire data on id '$sid'");
- return undef;
- }
-
- eval {
- $dbh->do(
- 'DELETE FROM '.$TABLE_NAME.' WHERE id = '.$dbh->quote($sid)
- );
- };
- if( $@ ) {
- $self->error("Couldn't release lock of '$sid'");
- return undef;
- }
-
- return 1;
-
- }
-
-
-
-
- # Called right before the object is destroyed to do cleanup
- sub teardown {
- my ($self, $sid, $options) = @_;
-
- my $dbh = $self->PostgreSQL_dbh($options);
-
- # Call commit if it isn't meant to be autocommited!
- unless ( $dbh->{AutoCommit} ) {
- $dbh->commit();
- }
-
- if ( $self->{PostgreSQL_disconnect} ) {
- $dbh->disconnect();
- }
-
- return 1;
- }
-
-
- sub PostgreSQL_dbh {
- my ($self, $options) = @_;
-
- my $args = $options->[1] || {};
-
- if ( defined $self->{PostgreSQL_dbh} ) {
- return $self->{PostgreSQL_dbh};
-
- }
-
- if ( defined $args->{TableName} ) {
- $TABLE_NAME = $args->{TableName};
- }
-
- require DBI;
-
- $self->{PostgreSQL_dbh} = $args->{Handle} || DBI->connect(
- $args->{DataSource},
- $args->{User} || undef,
- $args->{Password} || undef,
- { RaiseError=>1, PrintError=>1, AutoCommit=>1 } );
-
- # If we're the one established the connection,
- # we should be the one who closes it
- $args->{Handle} or $self->{PostgreSQL_disconnect} = 1;
-
- return $self->{PostgreSQL_dbh};
-
- }
-
-
-
-
- # $Id: PostgreSQL.pm,v 1.2 2003/03/01 12:46:55 cosimo Exp $
-
- 1;
-
- =pod
-
- =head1 NAME
-
- CGI::Session::PostgreSQL - PostgreSQL driver for CGI::Session
-
- =head1 SYNOPSIS
-
- use CGI::Session;
- $session = new CGI::Session("driver:PostgreSQL", undef, {Handle=>$dbh});
-
- For more examples, consult L<CGI::Session> manual
-
- =head1 DESCRIPTION
-
- CGI::Session::PostgreSQL is a CGI::Session driver to store session data in a PostgreSQL table.
- To write your own drivers for B<CGI::Session> refere L<CGI::Session> manual.
-
- =head1 STORAGE
-
- To store session data in PostgreSQL database, you first need
- to create a suitable table for it with the following command:
-
- CREATE TABLE sessions (
- id CHAR(32) NOT NULL,
- a_session TEXT NOT NULL
- );
-
-
- You can also add any number of additional columns to the table,
- but the above "id" and "a_session" are required.
- If you want to store the session data in other table than "sessions",
- you will also need to specify B<TableName> attribute as the
- first argument to new():
-
- use CGI::Session;
-
- $session = new CGI::Session("driver:PostgreSQL", undef,
- {Handle=>$dbh, TableName=>'my_sessions'});
-
- Every write access to session records is done through PostgreSQL own row locking mechanism,
- enabled by `FOR UPDATE' clauses in SELECTs or implicitly enabled in UPDATEs and DELETEs.
-
- =head1 COPYRIGHT
-
- 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.
-
- =head1 AUTHOR
-
- Cosimo Streppone <cosimo@cpan.org>, heavily based on the CGI::Session::MySQL
- driver by Sherzod Ruzmetov, original author of CGI::Session.
-
- =head1 SEE ALSO
-
- =over 4
-
- =item *
-
- L<CGI::Session|CGI::Session> - CGI::Session manual
-
- =item *
-
- L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
-
- =item *
-
- L<CGI::Session::CookBook|CGI::Session::CookBook> - practical solutions for real life problems
-
- =item *
-
- B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
-
- =item *
-
- L<CGI|CGI> - standard CGI library
-
- =item *
-
- L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
-
- =back
-
- =cut
-