home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / PostgreSQL.pm < prev    next >
Encoding:
Perl POD Document  |  2003-03-09  |  6.7 KB  |  297 lines

  1. # CGI::Session::PostgreSQL - PostgreSQL driver for CGI::Session
  2. #
  3. # Copyright (C) 2001-2002 Sherzod Ruzmetov, sherzodr@cpan.org
  4. #
  5. # Copyright (C) 2002 Cosimo Streppone, cosimo@cpan.org
  6. # This module is based on CGI::Session::MySql module
  7. # by Sherzod Ruzmetov, original author of CGI::Session modules
  8. # and CGI::Session::MySQL driver.
  9. #
  10. # 2002/12/08 cosimo@cpan.org
  11. #            Initial release
  12. # 2003/03/01 cosimo@cpan.org
  13. #            Added `FOR UPDATE' sql clauses to enable database row lock management
  14. #
  15. # $Id: PostgreSQL.pm,v 1.2 2003/03/01 12:46:55 cosimo Exp $
  16.  
  17. package CGI::Session::PostgreSQL;
  18.  
  19. use strict;
  20. # Inheriting necessary functionalities from the
  21. # following libraries. Do not change it unless you know
  22. # what you are doing
  23. use base qw(
  24.     CGI::Session
  25.     CGI::Session::ID::MD5
  26.     CGI::Session::Serialize::Default
  27. );
  28.  
  29.  
  30. # driver specific libraries should go below
  31.  
  32. use vars qw($VERSION $TABLE_NAME);
  33.  
  34. ($VERSION) = '$Revision: 1.2 $' =~ m/Revision:\s*(\S+)/;
  35. $TABLE_NAME = 'sessions';
  36.  
  37. ########################
  38. # Driver methods follow
  39. ########################
  40.  
  41.  
  42. # stores the serialized data. Returns 1 for sucess, undef otherwise
  43. sub store {
  44.  
  45.     my ($self, $sid, $options, $data) = @_;
  46.     my $dbh = $self->PostgreSQL_dbh($options);
  47.     my $db_data;
  48.  
  49.     eval {
  50.  
  51.         ($db_data) = $dbh->selectrow_array(
  52.             ' SELECT a_session FROM '.$TABLE_NAME.
  53.             ' WHERE id = '.$dbh->quote($sid).' FOR UPDATE'
  54.         );
  55.  
  56.     };
  57.  
  58.     if( $@ ) {
  59.         $self->error("Couldn't acquire data on id '$sid'");
  60.         return undef;
  61.     }
  62.  
  63.     eval {
  64.  
  65.         if( $db_data ) {
  66.  
  67. #warn('do update sid='.$sid.' data='.$self->freeze($data));
  68.  
  69.             $dbh->do(
  70.                 ' UPDATE '.$TABLE_NAME.
  71.                 ' SET a_session='.$dbh->quote($self->freeze($data)).
  72.                 ' WHERE id='.$dbh->quote($sid)
  73.             );
  74.  
  75.         } else {
  76.  
  77. #warn('do insert sid='.$sid.' data='.$self->freeze($data));
  78.  
  79.             $dbh->do(
  80.                 'INSERT INTO '.$TABLE_NAME.' (id,a_session) '.
  81.                 'VALUES ('.$dbh->quote($sid).', '.$dbh->quote($self->freeze($data)).')'
  82.             );
  83.  
  84.         }
  85.  
  86.     };
  87.  
  88.     if( $@ ) {
  89.         $self->error("Error in session update on id '$sid'. $@");
  90.         warn("Error in session update on id '$sid'. $@");
  91.         return undef;
  92.     }
  93.  
  94.     return 1;
  95. }
  96.  
  97.  
  98.  
  99. # retrieves the serialized data and deserializes it
  100. sub retrieve {
  101.     my ($self, $sid, $options) = @_;
  102.  
  103.     # after you get the data, deserialize it using
  104.     # $self->thaw(), and return it
  105.     my $dbh = $self->PostgreSQL_dbh($options);
  106.     my $data;
  107.     eval {
  108.         $data = $dbh->selectrow_array(
  109.             ' SELECT a_session FROM '.$TABLE_NAME.
  110.             ' WHERE id = '.$dbh->quote($sid)
  111.         );
  112.     };
  113.     if( $@ ) {
  114.         $self->error("Couldn't acquire data on id '$sid'");
  115.         return undef;
  116.     }
  117.     return $self->thaw($data);
  118. }
  119.  
  120.  
  121. # removes the given data and all the disk space associated with it
  122. sub remove {
  123.     my ($self, $sid, $options) = @_;
  124.  
  125.     my $dbh = $self->PostgreSQL_dbh($options);
  126.     my $data;
  127.     eval {
  128.         $data = $dbh->selectrow_array(
  129.             ' SELECT a_session FROM '.$TABLE_NAME.
  130.             ' WHERE id = '.$dbh->quote($sid).' FOR UPDATE'
  131.         );
  132.     };
  133.     if( $@ ) {
  134.         $self->error("Couldn't acquire data on id '$sid'");
  135.         return undef;
  136.     }
  137.  
  138.     eval {
  139.         $dbh->do(
  140.                 'DELETE FROM '.$TABLE_NAME.' WHERE id = '.$dbh->quote($sid)
  141.         );
  142.     };
  143.     if( $@ ) {
  144.         $self->error("Couldn't release lock of '$sid'");
  145.         return undef;
  146.     }
  147.  
  148.     return 1;
  149.  
  150. }
  151.  
  152.  
  153.  
  154.  
  155. # Called right before the object is destroyed to do cleanup
  156. sub teardown {
  157.     my ($self, $sid, $options) = @_;
  158.  
  159.     my $dbh = $self->PostgreSQL_dbh($options);
  160.  
  161.     # Call commit if it isn't meant to be autocommited!
  162.     unless ( $dbh->{AutoCommit} ) {
  163.         $dbh->commit();
  164.     }
  165.  
  166.     if ( $self->{PostgreSQL_disconnect} ) {
  167.         $dbh->disconnect();
  168.     }
  169.  
  170.     return 1;
  171. }
  172.  
  173.  
  174. sub PostgreSQL_dbh {
  175.     my ($self, $options) = @_;
  176.  
  177.     my $args = $options->[1] || {};
  178.  
  179.     if ( defined $self->{PostgreSQL_dbh} ) {
  180.         return $self->{PostgreSQL_dbh};
  181.  
  182.     }
  183.  
  184.     if ( defined $args->{TableName} ) {
  185.         $TABLE_NAME = $args->{TableName};
  186.     }
  187.  
  188.     require DBI;
  189.  
  190.     $self->{PostgreSQL_dbh} = $args->{Handle} || DBI->connect(
  191.                     $args->{DataSource},
  192.                     $args->{User}       || undef,
  193.                     $args->{Password}   || undef,
  194.                     { RaiseError=>1, PrintError=>1, AutoCommit=>1 } );
  195.  
  196.     # If we're the one established the connection,
  197.     # we should be the one who closes it
  198.     $args->{Handle} or $self->{PostgreSQL_disconnect} = 1;
  199.  
  200.     return $self->{PostgreSQL_dbh};
  201.  
  202. }
  203.  
  204.  
  205.  
  206.  
  207. # $Id: PostgreSQL.pm,v 1.2 2003/03/01 12:46:55 cosimo Exp $
  208.  
  209. 1;
  210.  
  211. =pod
  212.  
  213. =head1 NAME
  214.  
  215. CGI::Session::PostgreSQL - PostgreSQL driver for CGI::Session
  216.  
  217. =head1 SYNOPSIS
  218.  
  219.     use CGI::Session;
  220.     $session = new CGI::Session("driver:PostgreSQL", undef, {Handle=>$dbh});
  221.  
  222. For more examples, consult L<CGI::Session> manual
  223.  
  224. =head1 DESCRIPTION
  225.  
  226. CGI::Session::PostgreSQL is a CGI::Session driver to store session data in a PostgreSQL table.
  227. To write your own drivers for B<CGI::Session> refere L<CGI::Session> manual.
  228.  
  229. =head1 STORAGE
  230.  
  231. To store session data in PostgreSQL database, you first need
  232. to create a suitable table for it with the following command:
  233.  
  234.     CREATE TABLE sessions (
  235.         id CHAR(32) NOT NULL,
  236.         a_session TEXT NOT NULL
  237.     );
  238.  
  239.  
  240. You can also add any number of additional columns to the table,
  241. but the above "id" and "a_session" are required.
  242. If you want to store the session data in other table than "sessions",
  243. you will also need to specify B<TableName> attribute as the
  244. first argument to new():
  245.  
  246.     use CGI::Session;
  247.  
  248.     $session = new CGI::Session("driver:PostgreSQL", undef,
  249.                         {Handle=>$dbh, TableName=>'my_sessions'});
  250.  
  251. Every write access to session records is done through PostgreSQL own row locking mechanism,
  252. enabled by `FOR UPDATE' clauses in SELECTs or implicitly enabled in UPDATEs and DELETEs.
  253.  
  254. =head1 COPYRIGHT
  255.  
  256. Copyright (C) 2002 Cosimo Streppone. All rights reserved.
  257.  
  258. This library is free software and can be modified and distributed
  259. under the same terms as Perl itself.
  260.  
  261. =head1 AUTHOR
  262.  
  263. Cosimo Streppone <cosimo@cpan.org>, heavily based on the CGI::Session::MySQL
  264. driver by Sherzod Ruzmetov, original author of CGI::Session.
  265.  
  266. =head1 SEE ALSO
  267.  
  268. =over 4
  269.  
  270. =item *
  271.  
  272. L<CGI::Session|CGI::Session> - CGI::Session manual
  273.  
  274. =item *
  275.  
  276. L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
  277.  
  278. =item *
  279.  
  280. L<CGI::Session::CookBook|CGI::Session::CookBook> - practical solutions for real life problems
  281.  
  282. =item *
  283.  
  284. B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
  285.  
  286. =item *
  287.  
  288. L<CGI|CGI> - standard CGI library
  289.  
  290. =item *
  291.  
  292. L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
  293.  
  294. =back
  295.  
  296. =cut
  297.