use v5.34;
package Model::DB;
use Moo;
use Local::DB; # default action to auto-expand dates to DateTime objects
use Model::SQL; # provides app queries
use Data::Printer;
#-------------------------------------------------------------------------------
has app_config => ( is => 'ro', required => 1 ); # appdir, environment, etc
has dbix => (
is => 'lazy',
predicate => 1, # so we can call has_dbix
clearer => 1, # to remove object if db connection gone away
);
sub _build_dbix { # auto-expands dates to DateTime objects:
my $self = shift; $self->debug('creating new dbix object');
my $db = $self->app_config->{db_name};
Local::DB->dbix({ dbname => $db, log_query => 1 });
}
has sql_lib => ( is => 'lazy', clearer => 1, builder => sub {
# needs list of patient table cols - for demo only, not needed for live app:
Model::SQL->new( patient_cols => [ shift->dbix->get_cols('patients') ] )
} );
sub debug { # warn $ENV{DANCER_ENVIRONMENT}; p $_[0]->app_config;
p @_ if shift->app_config->{environment} =~ /^dev/;
}
#-------------------------------------------------------------------------------
sub get_user_details {
my ($self, $ref) = @_; # p $ref; # href key => userId (key = nhs-no, email or patient.id)
my ($sql, @bind) = $self->sql_lib->user_details($ref); # p $sql; p \@bind;
return $self->dbix->query($sql, @bind)->hash;
}
sub get_pack_dispatches {
my ($self, $patient_id) = @_; # p $patient_id;
my ($sql, @bind) = $self->sql_lib->get_pack_dispatches($patient_id); # p $sql; p \@bind;
return $self->dbix->query($sql, @bind)->hashes;
}
sub update_last_login {
my ($self, $patient_id) = @_; # p $patient_id;
my $now = 'NOW()'; # DateTime->now( time_zone => 'Europe/London' );
$self->dbix->update( 'patient_access',
{ last_login => \$now },
{ patient_id => $patient_id },
);
}
# check persistent dbix object still has an active db connection, if not then
# clear dbix object - will be re-created on demand when needed for next db query:
sub check_db_connection { # or _check_db_connection() - logs to sdtout:
my $self = shift; # say 'has dbix: '. ( $self->has_dbix || 'no' );
# call has_dbix() 1st in case object hasn't been created yet (dbix is lazy):
if ( $self->has_dbix and not $self->dbix->dbh->ping ) {
$self->clear_dbix;
}
return undef; # routine has no return value so don't return anything
}
#=begin # same as check_db_connection() but writes to stdout:
sub _check_db_connection {
my $self = shift; # say $self->has_dbix ? 'have dbix' : 'do not have dbix';
my $app_name = $self->app_config->{appname};
my @log = Local::Utils::time_now . " checking $app_name db connection:";
# call has_dbix() 1st in case object hasn't been created yet (dbix is lazy):
if ( $self->has_dbix ) {
my $id = $self->dbix->dbh->{mysql_thread_id};
push @log, "have dbix object (thread_id=$id), testing ping:";
if (! $self->dbix->dbh->ping ) {
push @log, '*** inactive ping ***, clearing dbix object';
$self->clear_dbix;
}
else { push @log, 'dbh still active' }
}
else { push @log, 'no dbix object' }
$self->debug(@log);
return undef; # routine has no return value so don't return anything
}
#=cut
1;