First pass at adding key files
This commit is contained in:
@ -0,0 +1,310 @@
|
||||
package GT::Session::TempTable;
|
||||
# ===============================================================
|
||||
# Pragmas
|
||||
use strict;
|
||||
use vars qw| $ATTRIBS @ISA $ERRORS |;
|
||||
|
||||
# Internal nodules
|
||||
use GT::Base;
|
||||
use GT::SQL;
|
||||
use GT::MD5 qw| md5_hex |;
|
||||
|
||||
# Global variable init
|
||||
@ISA = qw| GT::Base |;
|
||||
|
||||
$ATTRIBS = {
|
||||
id => undef,
|
||||
tb => undef,
|
||||
|
||||
def_path => '',
|
||||
db => undef,
|
||||
set_name => 'Set_Sessions',
|
||||
create_session => undef,
|
||||
delete_session => undef,
|
||||
seconds => 60*60,
|
||||
sid => ''
|
||||
};
|
||||
|
||||
$ERRORS = {
|
||||
'NODB' => "No GT::SQL object, need to set 'db' or 'def_path'",
|
||||
'NOCS' => "No session creation hook specified",
|
||||
'CSNOTCODE' => "Session creation hook is not a coderef",
|
||||
'NOSID' => "No session ID",
|
||||
'BADDATA' => "Invalid data in session: '%s'. Reason: '%s'",
|
||||
'CLASSFUNC' => "This is a class function only.",
|
||||
'INVALIDSESSION'=> "Invalid session id: '%s'.",
|
||||
'BADARGS' => "Invalid arguments: %s",
|
||||
|
||||
};
|
||||
|
||||
sub install {
|
||||
#-------------------------------------------------------------------------------
|
||||
# creates the controller table
|
||||
#
|
||||
my $self = shift;
|
||||
my $DB = $self->_db();
|
||||
|
||||
my $c = $DB->creator( $self->{set_name} );
|
||||
|
||||
$c->cols(
|
||||
ID => { pos => 1, type => 'INT', not_null => 1, unsigned => 1, regex => '^d+$' },
|
||||
SessID => { pos => 2, type => 'CHAR', size => 100, not_null => 1 },
|
||||
SessTable => { pos => 3, type => 'CHAR', size => 100, not_null => 1 },
|
||||
Timestmp => { pos => 4, type => 'TIMESTAMP', time_check => 1 }
|
||||
);
|
||||
|
||||
$c->pk('ID');
|
||||
$c->ai('ID');
|
||||
$c->create('force');
|
||||
$c->set_defaults();
|
||||
$c->save_schema();
|
||||
}
|
||||
|
||||
sub uninstall {
|
||||
#-------------------------------------------------------------------------------
|
||||
# drops the controller table along with all the
|
||||
#
|
||||
my $self = shift;
|
||||
my $DB = $self->_db() or return;
|
||||
my $err = 1;
|
||||
|
||||
# drop all the associated temp tables...,
|
||||
eval {
|
||||
my $tb = $DB->table( $self->{set_name} );
|
||||
my $sth = $tb->select( [ 'SessTable' ] );
|
||||
while ( my $aref = $sth->fetchrow_arrayref() ) {
|
||||
my $table_name = $aref->[0];
|
||||
eval {
|
||||
my $e = $DB->editor( $table_name );
|
||||
$e->drop_table("remove") or die "Can't drop table";
|
||||
};
|
||||
$@ and $err = undef;
|
||||
|
||||
}
|
||||
|
||||
# now drop the master control table
|
||||
my $e = $DB->editor( $self->{set_name});
|
||||
$e->drop_table("remove") or die "Can't drop table";
|
||||
};
|
||||
|
||||
return $@ ? undef : 1;
|
||||
}
|
||||
|
||||
sub new_set {
|
||||
#-------------------------------------------------------------------------------
|
||||
# creates a new temp table
|
||||
#
|
||||
my $self = shift;
|
||||
my $create_session = ( ref $_[0] eq 'CODE' ? shift : $self->{create_session} ) or return $self->error( 'NOCS', 'WARN' );
|
||||
|
||||
my $sid = $self->{id} or return $self->error( 'NOSID', 'WARN' );
|
||||
my $DB = $self->_db();
|
||||
my $Session = $DB->table( $self->{set_name} );
|
||||
|
||||
# create a new sesson
|
||||
my $table_name = generate_session_id();
|
||||
my $newid = $Session->add({ SessTable => $table_name, SessID => $sid }) or return;
|
||||
|
||||
# create the new table, extra parameters are passed into the create_session sub procedure
|
||||
if ( my $result = &{$create_session}( $DB, $table_name, $newid, @_ ) ) {
|
||||
my $tbl = $DB->table( $table_name );
|
||||
return wantarray ? ( $tbl, $newid ) : $tbl;
|
||||
}
|
||||
else {
|
||||
$Session->delete($newid);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub get_set {
|
||||
#-------------------------------------------------------------------------------
|
||||
# returns a table reference to the sethandle
|
||||
#
|
||||
my $self = shift;
|
||||
my $set_id = shift or return;
|
||||
my $sid = $self->{id} or return $self->error( 'NOSID', 'WARN' );
|
||||
|
||||
my $DB = $self->_db();
|
||||
my $Session = $DB->table( $self->{set_name} ) or return;
|
||||
my $sth = $Session->select({ ID => $set_id, SessID => $sid }) or return undef;
|
||||
my $href = $sth->fetchrow_hashref() or return undef;
|
||||
$href->{Timestmp} = \'NOW()';
|
||||
$Session->update( $href );
|
||||
|
||||
if ( my $table_name = $href->{'SessTable'} ) {
|
||||
my $tbl = $DB->table( $table_name );
|
||||
return $tbl;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sub list_sets {
|
||||
#-------------------------------------------------------------------------------
|
||||
# returns a hashref of ID => tablenames, of tables that the current session ID owns
|
||||
#
|
||||
my $self = shift;
|
||||
my $DB = $self->_db();
|
||||
|
||||
my $sid = $self->{id} or return $self->error( 'NOSID', 'WARN' );
|
||||
my $Session = $DB->table( $self->{set_name} ) or return;
|
||||
|
||||
my $sth = $Session->select({ SessID => $sid }, [ 'ID', 'SessTable' ]);
|
||||
my $list = {};
|
||||
while ( my $aref = $sth->fetchrow_arrayref() ) {
|
||||
my ( $id, $sesstable ) = @{$aref};
|
||||
$list->{$id} = $sesstable;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
sub delete {
|
||||
#-------------------------------------------------------------------------------
|
||||
# deletes all sets associated with the session
|
||||
#
|
||||
my $self = shift;
|
||||
my $DB = $self->_db();
|
||||
|
||||
my $Session = $DB->table( $self->{set_name} ) or return;
|
||||
my $sid = ( shift || $self->{id} ) or return $self->error( 'NOSID', 'WARN' );
|
||||
my $sth = $Session->select({ SessID => $sid },['SessTable']);
|
||||
|
||||
# delete all created temp tables
|
||||
while ( my $aref = $sth->fetchrow_arrayref() ) {
|
||||
my $tbl_name = $aref->[0];
|
||||
eval {
|
||||
my $e = $DB->editor($tbl_name);
|
||||
$e->drop_table( "remove" );
|
||||
}
|
||||
}
|
||||
|
||||
$Session->delete({ SessID => $sid });
|
||||
|
||||
# cheap workaround
|
||||
shift or $self->GT::Session::SQL::delete();
|
||||
}
|
||||
|
||||
sub delete_set {
|
||||
#-------------------------------------------------------------------------------
|
||||
# deletes a single set
|
||||
#
|
||||
my $self = shift;
|
||||
my $set_id = shift;
|
||||
|
||||
my $DB = $self->_db();
|
||||
my $Session = $DB->table( $self->{set_name} ) or return;
|
||||
my $sid = $self->{id} or return $self->error( 'NOSID', 'WARN' );
|
||||
my $sth = $Session->select( { ID => $set_id, SessID => $sid }, [ 'SessTable' ] ) or return;
|
||||
my $aref = $sth->fetchrow_arrayref() or return;
|
||||
|
||||
if ($aref->[0]) {
|
||||
my $e = $DB->editor($aref->[0]);
|
||||
$e->drop_table();
|
||||
$Session->delete( { ID => $set_id } );
|
||||
}
|
||||
}
|
||||
|
||||
sub cleanup {
|
||||
#-------------------------------------------------------------------------------
|
||||
my $self = shift;
|
||||
my $seconds = shift || $self->{seconds};
|
||||
|
||||
if ($seconds == 0) {
|
||||
$self->debug ("Cleanup not erasing anything, seconds set to 0.") if ($self->{_debug});
|
||||
return;
|
||||
}
|
||||
|
||||
my $DB = $self->_db() or return;
|
||||
my $tb = $DB->table( $self->{set_name} );
|
||||
|
||||
defined $seconds or ($seconds = 3600);
|
||||
my $new_sec = time - $seconds;
|
||||
my @time = localtime ($new_sec);
|
||||
|
||||
my $date_str = sprintf ("%4d-%02d-%02d %02d:%02d:%02d",
|
||||
$time[5] + 1900, $time[4] + 1, $time[3], $time[2], $time[1], $time[0]);
|
||||
|
||||
my $sth = $tb->select( GT::SQL::Condition->new('Timestmp', '<', $date_str), [ 'SessID' ] ) or return $self->error ($GT::SQL::error);
|
||||
while ( my $aref = $sth->fetchrow_arrayref() ) {
|
||||
$self->delete( $aref->[0], 1 );
|
||||
}
|
||||
$tb->delete (GT::SQL::Condition->new ('Timestmp', '<', $date_str)) or return $self->error ($GT::SQL::error);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _db {
|
||||
#-------------------------------------------------------------------------------
|
||||
# returns a database handle
|
||||
#
|
||||
my $self = shift;
|
||||
if ( my $db = $self->{'db'} ) {
|
||||
return $db;
|
||||
}
|
||||
|
||||
elsif ( my $def_path = $self->{'def_path'} ) {
|
||||
$db = GT::SQL->new( $def_path );
|
||||
return $db;
|
||||
}
|
||||
|
||||
else {
|
||||
$self->error( 'NODB', 'FATAL' );
|
||||
}
|
||||
}
|
||||
|
||||
sub generate_session_id {
|
||||
# ---------------------------------------------------------------
|
||||
# Generates a session id.
|
||||
#
|
||||
return md5_hex( time . $$ . rand (16000) );
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
GT::Session::TempTable - A session management module, subclassing GT::Session::SQL providing temp table support
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Create a session:
|
||||
my $session = new GT::Session::TempTable({
|
||||
db => GT::SQL->new( '/path/to/defs' ),
|
||||
def_path => '/path/to/defs',
|
||||
create_session => \&create_table_sub
|
||||
});
|
||||
|
||||
Create temp table controller table. (do once before using this module)
|
||||
$session->initial_create();
|
||||
|
||||
Create a new temp table:
|
||||
my ( $GT_SQL_Table_ref, $tmp_id ) = $session->new_set();
|
||||
|
||||
Get the GT::SQL::Table ref to a previous table:
|
||||
my $GT_SQL_Table_ref = $session->get_set( $tmp_id );
|
||||
|
||||
List all the sets for current session:
|
||||
my $href = $session->list_sets();
|
||||
|
||||
Save data with the session:
|
||||
$session->data ("Save this information!");
|
||||
|
||||
Load a session.
|
||||
my $session = new GT::Session::TempTable ( $id ) or die "Can't load session: '$id'."
|
||||
|
||||
Delete a session:
|
||||
$session->delete();
|
||||
|
||||
Delete a table set:
|
||||
$session->delete_set( $tmp_id );
|
||||
|
||||
Cleanup old sessions, takes argument of number of seconds old.
|
||||
$session->cleanup ( 5000 );
|
||||
|
||||
=cut
|
||||
|
Reference in New Issue
Block a user