ispman/lib/CGI/Session DB_File.pm,1.1,1.2 File.pm,1.1,1.2 MySQL.pm,1.1,1.2
Joerg Delker <[email protected]>
| Newsgroups | gmane.comp.isp.ispman.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ispman/ispman/lib/CGI/Session
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19629/Session
Modified Files:
DB_File.pm File.pm MySQL.pm
Log Message:
updated CGI::Session
Index: DB_File.pm
===================================================================
RCS file: /cvsroot/ispman/ispman/lib/CGI/Session/DB_File.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- DB_File.pm 30 May 2002 16:24:22 -0000 1.1
+++ DB_File.pm 7 Jul 2004 20:18:54 -0000 1.2
@@ -1,183 +1,168 @@
package CGI::Session::DB_File;
+# $Id$
+
use strict;
-use vars qw($VERSION);
-use base qw(CGI::Session CGI::Session::MD5);
+use base qw(
+ CGI::Session
+ CGI::Session::ID::MD5
+ CGI::Session::Serialize::Default
+);
-use File::Spec;
-use Data::Dumper;
-use Fcntl qw(:DEFAULT :flock);
use DB_File;
+use File::Spec;
+use Fcntl (':DEFAULT', ':flock');
-$VERSION = "2.4";
-
+# Load neccessary libraries below
-# do not use any indentation
-$Data::Dumper::Indent = 0;
+use vars qw($VERSION $FILE_NAME);
+$FILE_NAME = 'cgisess.db';
-sub retrieve {
- my ($self, $sid, $options) = @_;
+$VERSION = '0.1';
- my $file = $options->{FileName};
- my $lckdir = $options->{LockDirectory};
+sub store {
+ my ($self, $sid, $options, $data) = @_;
- my $lckfile = File::Spec->catfile($lckdir, "CGI-Session-$sid.lck");
- sysopen (LCK, $lckfile, O_RDWR|O_CREAT, 0664)
- or $self->error("Couldn't create lockfile $lckfile, $!"), return;
- flock (LCK, LOCK_SH)
- or $self->error("Couldn't lock $lckfile , $!"), return;
+ my $storable_data = $self->freeze($data);
- tie my %session, "DB_File", $file, O_RDWR|O_CREAT, 0777
- or $self->error("Couldn't open $file, $!"), return;
+ my $args = $options->[1];
+ my $file = File::Spec->catfile($args->{Directory}, $args->{FileName} || $FILE_NAME);
- my $tmp = $session{$sid} or $self->error("Session ID '$sid' doesn't exist"), return;
-
- untie %session;
- close (LCK);
+ tie my %db, "DB_File", $file, O_RDWR|O_CREAT, 0644 or die $!;
+ $db{$sid} = $storable_data;
+ untie(%db) or die $!;
- my $data = {}; eval $tmp;
+ return 1;
- return $data;
}
+sub retrieve {
+ my ($self, $sid, $options) = @_;
+ # you will need to retrieve the stored data, and
+ # deserialize it using $self->thaw() method
+ my $args = $options->[1];
+ my $file = File::Spec->catfile($args->{Directory}, $args->{FileName} || $FILE_NAME);
-sub store {
- my ($self, $sid, $hashref, $options) = @_;
+ tie my %db, "DB_File", $file, O_RDWR|O_CREAT, 0644 or die $!;
+ my $data = $self->thaw($db{$sid});
+ untie(%db);
- my $file = $options->{FileName};
- my $lckdir = $options->{LockDirectory};
+ return $data;
+}
- my $lckfile = File::Spec->catfile($lckdir, "CGI-Session-$sid.lck");
- sysopen (LCK, $lckfile, O_RDWR|O_CREAT, 0664) or $self->error("Couldn't create lockfile $lckfile, $!"), return;
- flock (LCK, LOCK_EX)
- or $self->error("Couldn't lock $lckfile, $!"), return;
-
- tie my %session, "DB_File", $file, O_RDWR|O_CREAT, 0777
- or $self->error("Couldn't open $file: $!"), return;
-
- my $d = Data::Dumper->new([$hashref], ["data"]);
-
- $session{$sid} = $d->Dump();
-
- untie %session;
- close (LCK);
+
+
+sub remove {
+ my ($self, $sid, $options) = @_;
+
+ # you simply need to remove the data associated
+ # with the id
+
+ my $args = $options->[1];
+ my $file = File::Spec->catfile($args->{Directory}, $args->{FileName} || $FILE_NAME);
+ tie my %db, "DB_File", $file, O_RDWR|O_CREAT, 0644 or die $!;
+ delete $db{$sid};
+ untie(%db) or die $!;
return 1;
-}
+}
-sub tear_down {
- my ($self, $sid, $options) = @_;
-
- my $file = $options->{FileName};
- my $lckdir = $options->{LockDirectory};
- tie (my %session, "DB_File", $file) or die $!;
- delete $session{$sid};
- untie %session;
+sub teardown {
+ my ($self, $sid, $options) = @_;
+
+ # this is called just before session object is destroyed
}
+
+
+
+# $Id$
+
1;
=pod
=head1 NAME
-CGI::Session::DB_File - Driver for CGI::Session class
+CGI::Session::DB_File - DB_File driver for CGI::Session
=head1 SYNOPSIS
- use constant COOKIE => "TEST_SID"; # cookie to store the session id
+ use CGI::Session;
+ $session = new CGI::Session("driver:DB_File", undef, {Directory=>'/tmp'});
- use CGI::Session::DB_File;
- use CGI;
+For more details, refer to L<CGI::Session> manual
- my $cgi = new CGI;
+=head1 DESCRIPTION
- # getting the
- my $c_sid = $cgi->cookie(COOKIE) || undef;
-
- my $session = new CGI::Session::DB_File($c_sid,
- {
- LockDirectory =>'/tmp/locks',
- FileName => '/tmp/sessions.db'
- });
-
- # now let's create a sid cookie and send it to the client's browser.
- # if it is an existing session, it will be the same as before,
- # but if it's a new session, $session->id() will return a new session id.
- {
- my $new_cookie = $cgi->cookie(-name=>COOKIE, -value=>$session->id);
- print $cgi->header(-cookie=>$new_cookie);
- }
+CGI::Session::DB_File is a CGI::Session driver to store session data in BerkeleyDB.
+Filename to store the session data is by default 'cgisess.db'. If you want different
+name, you can either specify it with the "FileName" option as below:
- print $cgi->start_html("CGI::Session::File");
+ $s = new CGI::Session::DB_File(undef, {Directory=>'/tmp', FileName=>'sessions.db'});
- # assuming we already saved the users first name in the session
- # when he visited it couple of days ago, we can greet him with
- # his first name
+or by setting the value of the $CGI::Session::DB_File::NAME variable before creating
+the session object:
- print "Hello", $session->param("f_name"), ", how have you been?";
+ $CGI::Session::DB_File::NAME = 'sessions.db';
+ $s = new CGI::Session("driver:DB_File", undef, {Directory=>'/tmp'});
- print $cgi->end_html();
+The only driver option required, as in the above examples, is "Directory", which tells the
+driver where the session file and lock files should be created.
-=head1 DESCRIPTION
+"FileName" option is also available, but not required.
-C<CGI::Session::DB_File> is the driver for C<CGI::Session> to store and retrieve
-the session data in and from the Berkeley DB 1.x. To be able to write your own
-drivers for the L<CGI::Session>, please consult L<developer section|CGI::Session/DEVEROPER SECTION>
-of the L<manual|CGI::Session>.
+=head1 COPYRIGHT
-Constructor requires two arguments, as all other L<CGI::Session> drivers do.
-The first argument has to be session id to be initialized (or undef to tell
-the L<CGI::Session> to create a new session id). The second argument has to be
-a reference to a hash with two following require key/value pairs:
+Copyright (C) 2001-2002 Sherzod Ruzmetov. All rights reserved.
-=over 4
+This library is free software and can be modified and distributed under the same
+terms as Perl itself.
-=item C<Filename>
+Bug reports should be directed to [email protected], or posted to [email protected]
+mailing list.
-path to a file where all the session data will be stored
+=head1 AUTHOR
-=item C<LockDirectory>
+CGI::Session::DB_File is written and maintained by Sherzod Ruzmetov <[email protected]>
-path in the file system where all the lock files for the sessions will be stored
+=head1 SEE ALSO
-=back
+=over 4
-C<CGI::Session::DB_File> uses L<Data::Dumper|Data::Dumper> to serialize the session data
-before storing it in the session file.
+=item *
-=head2 Example
-
- # get the sessino id either from the SID cookie, or from
- # the sid parameter in the URL
- my $c_sid = $cgi->cookie("SID") || $cgi->param("sid") || undef;
- my $session = new CGI::Session::DB_File($c_sid,
- {
- LockDirectory=>'/tmp',
- FileName=>'/tmp/sessions.db'
- });
+L<CGI::Session|CGI::Session> - CGI::Session manual
-For more extensive examples of the C<CGI::Session> usage, please refer to L<CGI::Session manual|CGI::Session>
+=item *
-=head1 AUTHOR
+L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
-Sherzod B. Ruzmetov <[email protected]>
+=item *
-=head1 COPYRIGHT
+L<CGI::Session::CookBook|CGI::Session::CookBook> - practical solutions for real life problems
-This library is free software and can be redistributed under the same
-conditions as Perl itself.
+=item *
-=head1 SEE ALSO
+B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
-L<CGI::Session>, L<CGI::Session::File>, L<CGI::Session::DB_File>,
-L<CGI::Session::MySQL>, L<Apache::Session>
+=item *
+
+L<CGI|CGI> - standard CGI library
+
+=item *
+
+L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
+
+=back
=cut
+
+# $Id$
Index: File.pm
===================================================================
RCS file: /cvsroot/ispman/ispman/lib/CGI/Session/File.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- File.pm 30 May 2002 16:24:22 -0000 1.1
+++ File.pm 7 Jul 2004 20:18:54 -0000 1.2
@@ -1,204 +1,190 @@
package CGI::Session::File;
-use strict;
-use vars qw($VERSION);
-use Carp;
-use base qw(CGI::Session CGI::Session::MD5);
+# $Id$
+use strict;
use File::Spec;
-use Fcntl qw(:DEFAULT :flock);
-use Data::Dumper;
+use Fcntl (':DEFAULT', ':flock');
+use base qw(
+ CGI::Session
+ CGI::Session::ID::MD5
+ CGI::Session::Serialize::Default
+);
-# do not use any indentation
-$Data::Dumper::Indent = 0;
-$VERSION = "2.4";
+use vars qw($FileName $VERSION);
+($VERSION) = '$Revision$' =~ m/Revision:\s*(\S+)/;
+$FileName = 'cgisess_%s';
-# constructor is inherited from CGI::Session
-sub retrieve {
- my ($self, $sid, $options) = @_;
+sub store {
+ my ($self, $sid, $options, $data) = @_;
- # getting the options passed to the constructor
- my $dir = $options->{Directory};
- my $lckdir = $options->{LockDirectory};
+ $self->File_init($sid, $options);
+ unless ( sysopen (FH, $self->{_file_path}, O_RDWR|O_CREAT|O_TRUNC, 0644) ) {
+ $self->error("Couldn't store $sid into $self->{_file_path}: $!");
+ return undef;
+ }
+ unless (flock(FH, LOCK_EX) ) {
+ $self->error("Couldn't get LOCK_EX: $!");
+ return undef;
+ }
+ print FH $self->freeze($data);
+ unless ( close(FH) ) {
+ $self->error("Couldn't close $self->{_file_path}: $!");
+ return undef;
+ }
+ return 1;
+}
- unless ( $dir && $lckdir ) {
- my $class = ref($self);
- croak "Usage: $class->new(\$sid, {Directory=>'/some/dir', LockDirectory=>'/some/dir'})";
- }
- # creating an OS independant path to the session file and the lockfile
- my $file = File::Spec->catfile($dir, "CGI-Session-$sid.dat");
- my $lckfile =File::Spec->catfile($lckdir, "CGI-Session-$sid.lck");
+sub retrieve {
+ my ($self, $sid, $options) = @_;
- # opening the lockfile
- sysopen(LCK, $lckfile, O_RDWR|O_CREAT, 0644) or $self->error("Couldn't create lockfile, $!"), return;
- flock(LCK, LOCK_SH) or $self->error("Couldn't acquire lock on $lckfile, $!"), return;
+ $self->File_init($sid, $options);
-
- # getting the data from the session file
- local ( $/, *FH );
- sysopen(FH, $file, O_RDONLY) or $self->error("Couldn't open data file ($file), $!"), return;
- my $tmp = <FH>;
- close (FH); close (LCK);
+ # If the session data does not exist, return.
+ unless ( -e $self->{_file_path} ) {
+ return undef;
+ }
+
+ unless ( sysopen(FH, $self->{_file_path}, O_RDONLY) ) {
+ $self->error("Couldn't open $self->{_file_path}: $!");
+ return undef;
+ }
+ unless (flock(FH, LOCK_SH) ) {
+ $self->error("Couldn't lock the file: $!");
+ return undef;
+ }
+ my $data = undef;
+ $data .= $_ while <FH>;
+
+ close(FH);
+ return $self->thaw($data);
+}
- # intializing the hashref
- my $data = {}; eval $tmp;
- # did something go wrong?
- if ( $@ ) { $self->error("Couldn't eval() the data, $!"), return }
- # returning the eval()ed data
- return $data;
+sub remove {
+ my ($self, $sid, $options) = @_;
+
+ $self->File_init($sid, $options);
+ unless ( unlink ( $self->{_file_path} ) ) {
+ $self->error("Couldn't unlink $self->{_file_path}: $!");
+ return undef;
+ }
+ return 1;
}
-sub store {
- my ($self, $sid, $hashref, $options) = @_;
- # getting the options passed to the constructor
- my $dir = $options->{Directory};
- my $lckdir = $options->{LockDirectory};
+sub teardown {
+ my ($self, $sid, $options) = @_;
- # creating an OS independant path
- my $file = File::Spec->catfile($dir, "CGI-Session-$sid.dat");
- my $lckfile = File::Spec->catfile($lckdir, "CGI-Session-$sid.lck");
-
+ return 1;
+}
- # opening the lockfile
- sysopen (LCK, $lckfile, O_RDWR|O_CREAT, 0664) or $self->error("Couldn't open $lckfile, $!"), return;
- flock(LCK, LOCK_EX) or $self->error("Couldn't acquire lock on $lckfile, $!"), return;
- # storing the data in the session file
- local (*FH);
- sysopen (FH, $file, O_RDWR|O_CREAT|O_TRUNC, 0664) or $self->error("Couldn't create $file, $!"), return;
- # creating a Data::Dumper object of $hashref
- my $d = Data::Dumper->new([$hashref], ["data"]);
- # dumping the $hashref into a session file
- print FH $d->Dump();
- close (FH); close LCK;
+sub File_init {
+ my ($self, $sid, $options) = @_;
- return 1;
+ my $dir = $options->[1]->{Directory};
+ my $path = File::Spec->catfile($dir, sprintf("$FileName", $sid));
+ $self->{_file_path} = $path;
}
-sub tear_down {
- my ($self, $sid, $options) = @_;
-
- # getting the options passed to the constructor
- my $dir = $options->{Directory};
-
- # discovering the session filename
- my $file = File::Spec->catfile($dir, "CGI-Session-$sid.dat");
- # deleting the file
- unlink $file or $self->error("Couldn't delete the session data $file: $!"), return;
- return 1;
-}
+# $Id$
-1;
+1;
=pod
=head1 NAME
-CGI::Session::File - CGI::Session driver for
+CGI::Session::File - Default CGI::Session driver
+
+=head1 REVISION
+
+This manual refers to $Revision$
=head1 SYNOPSIS
+
+ use CGI::Session;
+ $session = new CGI::Session("driver:File", undef, {Directory=>'/tmp'});
- use constant COOKIE => "TEST_SID"; # cookie to store the session id
+For more examples, consult L<CGI::Session> manual
- use CGI::Session::File;
- use CGI;
+=head1 DESCRIPTION
- my $cgi = new CGI;
+CGI::Session::File is a default CGI::Session driver. Stores the session data
+in plain files. For the list of available methods, consult L<CGI::Session> manual.
- # getting the session id from the cookie
- my $c_sid = $cgi->cookie(COOKIE) || undef;
-
- my $session = new CGI::Session::File($c_sid,
- {
- LockDirectory =>'/tmp/locks',
- Directory =>'/tmp/sessions'
- });
-
- # now let's create a sid cookie and send it to the client's browser.
- # if it is an existing session, it will be the same as before,
- # but if it's a new session, $session->id() will return a fresh one
- {
- my $new_cookie = $cgi->cookie(-name=>COOKIE, -value=>$session->id);
- print $cgi->header(-cookie=>$new_cookie);
- }
+Each session is stored in a seperate file. File name is by default formatted as "cgisess_%s",
+where '%s' is replaced with the effective session id. To change file name formatting,
+update $CGI::Session::File::NAME variable. Examples:
- print $cgi->start_html("CGI::Session::File");
+ $CGI::Session::File::FileName = 'cgisess_%s.dat'; # with .dat extention
+ $CGI::Session::File::FileName = '%s.session';
+ $CGI::Session::File::FileName = '%CGI-Session-%s.dat'; # old style
- # assuming we already saved the users first name in the session
- # when he visited it couple of days ago, we can greet him with
- # his first name
+The only driver option required is 'Directory', which denotes the location
+session files are stored in.
- print "Hello", $session->param("f_name"), ", how have you been?";
+Example:
- print $cgi->end_html();
+ $session = new CGI::Session("driver:File", undef, {Directory=>'some/directory'});
-=head1 DESCRIPTION
+=head1 COPYRIGHT
-C<CGI::Session::File> is the driver for the L<CGI::Session|CGI::Session> to store and retrieve
-the session data in and from the plain text files. To be able to write your own
-drivers for the L<CGI::Session|CGI::Session>, please consult L<developer section|CGI::Session/DEVELOPER SECTION>
-of the L<manual|CGI::Session>
+Copyright (C) 2001-2002 Sherzod Ruzmetov. All rights reserved.
-Constructor requires two arguments, as all other L<CGI::Session> drivers do.
-The first argument has to be session id to be initialized (or undef to tell
-the CGI::Session to create a new session id). The second argument has to be
-a reference to a hash with two following require key/value pairs:
+This library is free software and can be modified and distributed under the same
+terms as Perl itself.
-=over 4
+Bug reports should be directed to [email protected], or posted to [email protected]
+mailing list.
-=item C<Directory>
+=head1 AUTHOR
-path in the file system where all the session data will be stored
+CGI::Session::File is written and maintained by Sherzod Ruzmetov <[email protected]>
-=item C<LockDirectory>
+=head1 SEE ALSO
-path in the file system where all the lock files for the sessions will be stored
+=over 4
-=back
+=item *
-C<CGI::Session::File> uses L<Data::Dumper|Data::Dumper> to serialize the session data
-before storing it in the session file.
+L<CGI::Session|CGI::Session> - CGI::Session manual
-=head2 Example
-
- # get the sessino id either from the SID cookie, or from
- # the sid parameter in the URL
- my $c_sid = $cgi->cookie("SID") || $cgi->param("sid") || undef;
- my $session = new CGI::Session::File($c_sid,
- {
- LockDirectory => '/tmp',
- Directory => '/tmp'
- });
+=item *
-For more extensive examples of the L<CGI::Session|CGI::Session> usage, please refer to
-L<CGI::Session> manual.
+L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
-=head1 AUTHOR
+=item *
-Sherzod B. Ruzmetov <[email protected]>
+L<CGI::Session::CookBook|CGI::Session::CookBook> - practical solutions for real life problems
-=head1 COPYRIGHT
+=item *
-This library is free software and can be redistributed under the same
-conditions as Perl itself.
+B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
-=head1 SEE ALSO
+=item *
-L<CGI::Session>, L<CGI::Session::File>, L<CGI::Session::DB_File>,
-L<CGI::Session::MySQL>, L<Apache::Session>
+L<CGI|CGI> - standard CGI library
+
+=item *
+
+L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
+
+=back
=cut
+
+# $Id$
Index: MySQL.pm
===================================================================
RCS file: /cvsroot/ispman/ispman/lib/CGI/Session/MySQL.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- MySQL.pm 30 May 2002 16:24:22 -0000 1.1
+++ MySQL.pm 7 Jul 2004 20:18:54 -0000 1.2
@@ -1,103 +1,114 @@
package CGI::Session::MySQL;
+# $Id$
+
use strict;
-use vars qw($VERSION $TABLE_NAME);
-use base qw(CGI::Session CGI::Session::MD5);
+# 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
+);
-use Data::Dumper;
-use Carp;
-eval "require DBI";
-if ( $@ ) {
- $CGI::Session::errstr = $@;
-}
+# driver specific libraries should go below
-$VERSION = "2.3";
+use vars qw($VERSION $TABLE_NAME);
-# chose the most compat from of serialization in Data::Dumper
-$Data::Dumper::Indent = 0;
+($VERSION) = '$Revision$' =~ m/Revision:\s*(\S+)/;
-# This is the sessions table. Change it if you want to
-# use some other table for your sessions data
$TABLE_NAME = 'sessions';
-# returns $dbh and $lckh
-sub MYSQL_dbh {
- my ($self, $option) = @_;
+########################
+# Driver methods follow
+########################
- my $dbh = $option->{Handle};
- my $lckh = $option->{LockHandle};
- my $dsn = $option->{DataSource};
- my $username= $option->{UserName};
- my $psswd = $option->{Password};
- my $lcksn = $option->{LockDataSource} || $dsn;
- my $lckuser = $option->{LockUserName} || $username;
- my $lckpsswd= $option->{LockPassword} || $psswd;
- if ( $dbh && $lckh ) {
- return ($dbh, $lckh);
- }
+# stores the serialized data. Returns 1 for sucess, undef otherwise
+sub store {
+ my ($self, $sid, $options, $data) = @_;
- $dbh = DBI->connect($dsn, $username, $psswd) or $self->error($DBI::errstr), return;
- $lckh = DBI->connect($lcksn, $lckuser, $lckpsswd) or $self->error($DBI::errstr), return;
+ my $dbh = $self->MySQL_dbh($options);
+ my $lck_status = $dbh->selectrow_array(qq|SELECT GET_LOCK("$sid", 10)|);
+ unless ( $lck_status == 1 ) {
+ $self->error("Couldn't acquire lock on id '$sid'. Lock status: $lck_status");
+ return undef;
+ }
- return ($dbh, $lckh);
+ $dbh->do(qq|REPLACE INTO $TABLE_NAME (id, a_session) VALUES(?,?)|,
+ undef, $sid, $self->freeze($data));
+
+ return $dbh->selectrow_array(qq|SELECT RELEASE_LOCK("$sid")|);
}
-
-
-
-
-
-
+# retrieves the serialized data and deserializes it
sub retrieve {
- my ($self, $sid, $option) = @_;
-
- my ($dbh, $lckh) = $self->MYSQL_dbh($option) or return;
- $lckh->do("LOCK TABLES $TABLE_NAME READ");
-
- my ($tmp) = $dbh->selectrow_array(qq|SELECT a_session FROM $TABLE_NAME WHERE id=?|, undef, $sid);
+ my ($self, $sid, $options) = @_;
- $lckh->do("UNLOCK TABLES");
-
- my $data = {}; eval $tmp;
+ # after you get the data, deserialize it using
+ # $self->thaw(), and return it
+ my $dbh = $self->MySQL_dbh($options);
+ my $lck_status = $dbh->selectrow_array(qq|SELECT GET_LOCK("$sid", 10)|);
+ unless ( $lck_status == 1 ) {
+ $self->error("Couldn't acquire lock on is '$sid'. Lock status: $lck_status");
+ return undef;
+ }
- if ( $@ ) {
- $self->error("Couldn't eval() the data, $@"), return;
- }
+ my $data = $dbh->selectrow_array(qq|SELECT a_session FROM $TABLE_NAME WHERE id=?|, undef, $sid);
+ $lck_status = $dbh->selectrow_array(qq|SELECT RELEASE_LOCK("$sid")|);
+ unless ( $lck_status == 1 ) {
+ $self->error("Couldn't release lock of '$sid'. Lock status: $lck_status");
+ return undef;
+ }
- return $data;
+ 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->MySQL_dbh($options);
+ my $lck_status = $dbh->selectrow_array(qq|SELECT GET_LOCK("$sid", 10)|);
+ unless ( $lck_status == 1 ) {
+ $self->error("Couldn't acquire lock on id '$sid'. Lock status; $lck_status");
+ return undef;
+ }
+ $dbh->do(qq|DELETE FROM $TABLE_NAME WHERE id=?|, undef, $sid);
+ $lck_status = $dbh->selectrow_array(qq|SELECT RELEASE_LOCK("$sid")|);
+ unless ( $lck_status == 1 ) {
+ $self->error("Couldn't release lock of '$sid'. Lock status: $lck_status");
+ return undef;
+ }
+
+ return 1;
+}
+# called right before the object is destroyed to do cleanup
+sub teardown {
+ my ($self, $sid, $options) = @_;
+ my $dbh = $self->MySQL_dbh($options);
-sub store {
- my ($self, $sid, $hashref, $option) = @_;
-
- my ($dbh, $lckh) = $self->MYSQL_dbh($option);
- my $d = Data::Dumper->new([$hashref], ["data"]);
- my $exists = $dbh->selectrow_array(qq|SELECT a_session FROM $TABLE_NAME WHERE id=?|, undef, $sid);
-
- $lckh->do("LOCK TABLES $TABLE_NAME WRITE");
-
- if ( $exists ) {
- my $rv = $dbh->do(qq|UPDATE $TABLE_NAME SET a_session=? WHERE id=?|, undef, $d->Dump(), $sid);
- $lckh->do("UNLOCK TABLES");
- return $rv;
+ # Call commit if it isn't meant to be autocommited!
+ unless ( $dbh->{AutoCommit} ) {
+ $dbh->commit();
+ }
+
+ if ( $self->{MySQL_disconnect} ) {
+ $dbh->disconnect();
}
- my $rv = $dbh->do(qq|INSERT INTO $TABLE_NAME SET id=?, a_session=?|, undef, $sid, $d->Dump());
- $lckh->do("UNLOCK TABLES");
- return $rv;
+ return 1;
}
@@ -105,173 +116,124 @@
+sub MySQL_dbh {
+ my ($self, $options) = @_;
+ my $args = $options->[1] || {};
+
+ if ( defined $self->{MySQL_dbh} ) {
+ return $self->{MySQL_dbh};
-sub tear_down {
- my ($self, $sid, $option) = @_;
+ }
+
+ require DBI;
- my ($dbh, $lckh) = $self->MYSQL_dbh($option);
+ $self->{MySQL_dbh} = $args->{Handle} || DBI->connect(
+ $args->{DataSource},
+ $args->{User} || undef,
+ $args->{Password} || undef,
+ { RaiseError=>1, PrintError=>1, AutoCommit=>1 } );
- $lckh->do("LOCK TABLES $TABLE_NAME WRITE");
- my $rv = $dbh->do(qq|DELETE FROM $TABLE_NAME WHERE id=?|, undef, $sid);
- $lckh->do("UNLOCK TABLES");
- return $rv;
+ # If we're the one established the connection,
+ # we should be the one who closes it
+ $args->{Handle} or $self->{MySQL_disconnect} = 1;
+ return $self->{MySQL_dbh};
+
}
+# $Id$
-
-
-1;
-
-
+1;
=pod
=head1 NAME
-CGI::Session::MySQL - Driver for CGI::Session class
+CGI::Session::MySQL - MySQL driver for CGI::Session
=head1 SYNOPSIS
+
+ use CGI::Session;
+ $session = new CGI::Session("driver:MySQL", undef, {Handle=>$dbh});
- use constant COOKIE => "TEST_SID"; # cookie to store the session id
-
- use CGI::Session::MySQL;
- use CGI;
- use DBI;
-
- my $dbh = DBI->connect("DBI:mysql:dev", "dev", "marley01");
- my $cgi = new CGI;
-
- # getting the session id from the cookie
- my $c_sid = $cgi->cookie(COOKIE) || undef;
-
- my $session = new CGI::Session::MySQL($c_sid,
- {
- LockHandle => $dbh,
- Handle => $dbh
- });
-
- # now let's create a sid cookie and send it to the client's browser.
- # if it is an existing session, it will be the same as before,
- # but if it's a new session, $session->id() will return a new session id.
- {
- my $new_cookie = $cgi->cookie(-name=>COOKIE, -value=>$session->id);
- print $cgi->header(-cookie=>$new_cookie);
- }
-
- print $cgi->start_html("CGI::Session::MySQL");
-
- # assuming we already saved the users first name in the session
- # when he visited it couple of days ago, we can greet him with
- # his first name
-
- print "Hello", $session->param("f_name"), ", how have you been?";
-
- print $cgi->end_html();
+For more examples, consult L<CGI::Session> manual
=head1 DESCRIPTION
-C<CGI::Session::MySQL> is the driver for the L<CGI::Session> class to store
-and retrieve the session data in and from the MySQL database
-
-To be able to write your own drivers for L<CGI::Session>, please consult
-L<CGI::Session manual|CGI::Session>.
+CGI::Session::MySQL is a CGI::Session driver to store session data in MySQL table.
+To write your own drivers for B<CGI::Session> refere L<CGI::Session> manual.
-Constructor requires two arguments, as all other L<CGI::Session> drivers do.
-The first argument has to be session id to be initialized (or undef to tell
-the L<CGI::Session> to create a new session id). The second argument has to be
-a reference to a hash with two following required key/value pairs:
-=over 4
+=head1 STORAGE
-=item C<Handle>
+To store session data in MySQL database, you first need to create a suitable table for it
+with the following command:
-this has to be a database handler returned from the C<DBI->connect()>
-(see L<DBI manual|DBI>, L<DBD::mysql manual|DBD::mysql>)
+ CREATE TABLE sessions (
+ id CHAR(32) NOT NULL UNIQUE,
+ a_session TEXT NOT NULL
+ );
-=item C<LockHandle>
-This is also a handler returned from the C<DBI->connect()> for locking the sessions
-table.
+You can also add any number of additional columns to the table, but the above "id"
+and "a_session" are required.
-=back
+If you want to store the session data in other table than "sessions", before creating
+the session object you need to set the special variable B<$CGI::Session::MySQL::TABLE_NAME>
+to the name of the table:
-You can also ask C<CGI::Session::MySQL> to create a handler for you. To do this
-you will need to pass it the following key/value pairs as the second argument:
+ use CGI::Session;
-=over 4
+ $CGI::Session::MySQL::TABLE_NAME = 'my_sessions';
+ $session = new CGI::Session("driver:MySQL", undef, {Handle=>$dbh});
-=item C<DataSource>
+=head1 COPYRIGHT
-Name of the datasource L<DBI> has to use. Usually C<DBI:mysql:db_name>
+Copyright (C) 2001, 2002 Sherzod Ruzmetov. All rights reserved.
-=item C<UserName>
+This library is free software and can be modified and distributed under the same
+terms as Perl itself.
-Username who is able to access the above C<DataSource>
-=item C<Password>
+=head1 AUTHOR
-Password the C<UserName> has to provide to be able to access the C<DataSource>.
+Sherzod Ruzmetov <[email protected]>. All the bug reports should be sent to the author
+to [email protected]>
-=back
+=head1 SEE ALSO
-It also expects C<LockDatasource>, C<LockUserName> and C<LockPassword> key/values,
-but if they are missing defaults to the ones provided by C<DataSource>, C<UserName>
-and C<Password> respectively.
+=over 4
-C<CGI::Session::MySQL> uses L<Data::Dumper|Data::Dumper> to serialize the session data
-before storing it in the session file.
+=item *
-=head1 STORAGE
+L<CGI::Session|CGI::Session> - CGI::Session manual
-Since the data should be stored in the mysql table, you will first need to
-create a sessions table in your mysql database. The following command should
-suffice for basic use of the library:
+=item *
- CREATE TABLE sessions (
- id CHAR(32) NOT NULL PRIMARY KEY,
- a_session TEXT
- );
+L<CGI::Session::Tutorial|CGI::Session::Tutorial> - extended CGI::Session manual
-=head1 Example
-
- # get the sessino id either from the SID cookie, or from
- # the sid parameter in the URL
- my $c_sid = $cgi->cookie("SID") || $cgi->param("sid") || undef;
- my $session = new CGI::Session::MySQL($c_sid,
- {
- Handle => $dbh,
- LockHandle => $dbh
- });
+=item *
-For more extensive examples of the L<CGI::Session> usage, please refer to
-the L<manual|CGI::Session>
+L<CGI::Session::CookBook|CGI::Session::CookBook> - practical solutions for real life problems
-=head1 BUGS
+=item *
-Currently no bugs have been detected, but eval() in retrive() method
-produces the following error:
+B<RFC 2965> - "HTTP State Management Mechanism" found at ftp://ftp.isi.edu/in-notes/rfc2965.txt
- Use of uninitialized value in string at blib/lib/CGI/Session/MySQL.pm line 65.
+=item *
-Of which I am quite embarrased. Coulld not figure out how to get rid of it.
-So if you can think of any solution, please take this guilt off my conscious
-ASAP.
+L<CGI|CGI> - standard CGI library
-=head1 AUTHOR
+=item *
-Sherzod B. Ruzmetov <[email protected]>
+L<Apache::Session|Apache::Session> - another fine alternative to CGI::Session
-=head1 COPYRIGHT
+=back
-This library is free software and can be redistributed under the same
-conditions as Perl itself.
+=cut
-=head1 SEE ALSO
-L<CGI::Session>, L<CGI::Session::File>, L<CGI::Session::DB_File>,
-L<CGI::Session::MySQL>, L<Apache::Session>
-=cut
+# $Id$
-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 -
digital self defense, top technical experts, no vendor pitches,
unmatched networking opportunities. Visit www.blackhat.com