package CGI::Armature::Bridge; use strict; sub new { my $class = shift; my $object_ref = shift; my $method_map = shift; my $self = { object=>$object_ref, }; $self-{$_} = $method_map->{$_} for keys %$method_map; return bless($self, $class); } 1; #### package CGI::Armature::Serializer; use strict; use vars '@ISA'; BEGIN { require CGI::Armature::Bridge; @ISA = 'CGI::Armature::Bridge'; } sub serialize { my $self = shift; my $hash = shift; my $method = $self->{serialize}; return $self->{object}->$method($hash); } sub deserialize { my $self = shift; my $data = shift; my $method = $self->{deserialize}; return $self->{object}->$method($data); } 1; #### use CGI::Armature::Serializer; use XML::Simple; my $serialize_map = { serialize=>'XMLin', deserialize=>'XMLout', }; my $serializer = CGI::Armature::Serializer->new( XML::Simple->new(suppressempty=>q{}, noattr=>1), $serialize_map, ); #### use CGI::Armature::Serializer; use YAML; my $serialize_map = { serialize=>'Dump', deserialize=>'Load', }; my $serializer = CGI::Armature::Serializer->new( YAML->new(), $serialize_map, ); #### $data = $serializer->serialize($data_hash); $data_hash = $serializer->deserialize($data); #### package CGI::Armature::Storage; use strict; use vars '@ISA'; BEGIN { require CGI::Armature::Bridge; @ISA = 'CGI::Armature::Bridge'; } sub fetch { my $self = shift; my $id = shift; my $method = $self->{fetch}; return $self->{object}->$method($id); } sub store { my $self = shift; my $id = shift; my $value = shift; my $method = $self->{store}; $self->{object}->$method($id, $value); } sub fetch_ids { my $self = shift; my $method = $self->{fetch_ids}; return $self->{object}->$method(); } sub delete { my $self = shift; my $id = shift; my $method = $self->{delete}; $self->{object}->$method($id); } 1; #### package CGI::Armature::Database; use strict; use Fcntl; use DB_File::Lock; use CGI::Armature::PathInfo; my %path_info = CGI::Armature::PathInfo::get_paths(); sub new { my $class = shift; my ($dbfile) = @_; die "need dbfile" unless $dbfile; my $self = { dbfile=>$dbfile, }; return bless($self, $class); } sub create { my $self = shift; my %db_file; my $locking = { mode=>'write', lockfile_name=>"$path_info{sessionpath}/exclusive.lock", }; tie( %db_file, 'DB_File::Lock', "$path_info{sessionpath}/$self->{dbfile}", O_RDWR|O_CREAT, 0600, $DB_HASH, $locking, ) or die "Couldn't tie DB_File $path_info{sessionpath}/$self->{dbfile} $!; aborting"; untie %db_file; } sub delete { my $self = shift; my $key = shift; my %db_file; my $locking = { mode=>'write', lockfile_name=>"$path_info{sessionpath}/exclusive.lock", }; tie( %db_file, 'DB_File::Lock', "$path_info{sessionpath}/$self->{dbfile}", O_RDWR, 0600, $DB_HASH, $locking, ) or die "Couldn't tie DB_File $path_info{sessionpath}/$self->{dbfile} $!; aborting"; delete $db_file{$key}; untie %db_file; } sub set_value { my $self = shift; die "not enough values for set_value" unless @_ == 2; my ($key, $value) = @_; my %db_file; my $locking = { mode=>'write', lockfile_name=>"$path_info{sessionpath}/exclusive.lock", }; tie( %db_file, 'DB_File::Lock', "$path_info{sessionpath}/$self->{dbfile}", O_RDWR, 0600, $DB_HASH, $locking, ) or die "Couldn't tie DB_File $path_info{sessionpath}/$self->{dbfile} $!; aborting"; $db_file{$key} = $value; untie %db_file; } sub get_value { my $self = shift; my $key = shift; my %db_file; my $locking = { mode=>'read', lockfile_name=>"$path_info{sessionpath}/exclusive.lock", }; tie( %db_file, 'DB_File::Lock', "$path_info{sessionpath}/$self->{dbfile}", O_RDONLY, 0600, $DB_HASH, $locking, ) or die "Couldn't tie DB_File $path_info{sessionpath}/$self->{dbfile} $!; aborting"; my $value = $db_file{$key}; untie %db_file; return $value; } sub get_keys { my $self = shift; my %db_file; my $locking = { mode=>'read', lockfile_name=>"$path_info{sessionpath}/exclusive.lock", }; tie( %db_file, 'DB_File::Lock', "$path_info{sessionpath}/$self->{dbfile}", O_RDONLY, 0600, $DB_HASH, $locking, ) or die "Couldn't tie DB_File $path_info{sessionpath}/$self->{dbfile} $!; aborting"; my @keys = keys %db_file; untie %db_file; return \@keys; } 1; #### use CGI::Armature::Storage; use CGI::Armature::Database; my $storage_map = { fetch=>'get_value', store=>'set_value', fetch_ids=>'get_keys', delete=>'delete', }; my $storage = CGI::Armature::Storage->new( CGI::Armature::Database->new('session_id.db'), $storage_map, ); my $data = $storage->fetch($session_id);