package Dancer2::Session::DBIx;
# needs to be called Dancer2::Session::DBIx not Local::D2::Session::DBIx otherwise
# Dancer2::Core::Factory::create cannot find it:
# my $component_class = "Dancer2::${type}::${name}";
use 5.26.0;
use Data::Printer;
use Storable qw(freeze thaw);
# use Local::DB; # get MySQL has gone away in production
use DBIx::Simple;
use Local::MooX::Types qw/HashReference/;
use Moo;
# passed in from config as engines/Session/DBIx:
has $_ => ( is => 'ro' ) for qw( dsn dbname );
has dbix => (
is => 'lazy', # maybe responsible for mysql-gone-away error ?
# can't do this, get MySQL has gone away in production:
# builder => sub { Local::DB->dbix({ dbname => shift->dbname }) },
builder => sub { DBIx::Simple->connect(shift->dsn) },
);
has cache => ( is => 'rw', isa => HashReference, default => sub { {} } );
with 'Dancer2::Core::Role::SessionFactory';
#--------------------------------------------------------------------------#
# SessionFactory implementation methods
#--------------------------------------------------------------------------#
sub _retrieve {
my ( $self, $id ) = @_; # p $self->cache;
my $session = $self->dbix->select('sessions', '*', { id => $id } )->hash;
my $data = $self->_deserialize($session->{a_session}); # ddp $data;
return $data;
}
sub _flush {
my ( $self, $id, $data ) = @_; # p $data;
local $ENV{SQL_TRACE} = 0; # to prevent query output for storable data
my $store = $self->_serialize($data);
# if ( $self->dbix->select('sessions', 1, { id => $id } )->list ) { # update:
if ( $self->cache->{session_id} ) { # need to delete before insert in case app restarted, or get duplicate key err:
$self->dbix->update('sessions', { a_session => $store }, { id => $id });
#my $user = $data->{user_profile}; # to update userid col
#my $userid = join '.', $user->{first_name}, $user->{last_name};
}
else { # insert:
$self->_destroy($id); # need to delete 1st if using cache in case app restarted
$self->dbix->insert('sessions',
{ id => $id, a_session => $store, created => \'NOW()' } );
$self->cache( { session_id => $id } ); # to prevent any more queries for $id
}
}
sub _destroy {
my ( $self, $id ) = @_;
$self->dbix->delete('sessions', { id => $id });
}
sub _sessions {
my ($self) = @_;
my $all = $self->dbix->select('sessions', 'id')->list;
return $all;
}
#-------------------------------------------------------------------------------
sub _serialize {
my ($self, $data) = @_;
return freeze $data;
}
sub _deserialize {
my ($self, $serialised) = @_;
return thaw $serialised;
}
1;