package LIMS::Model::Base;
# base package for LIMS::Model classes that want $self->user_profile
# generic Rose::DB::Object::Manager methods - all require $args
# (hashref of object_class (required) & args_for_search (optional)
use Moose;
with 'LIMS::Model::Roles::SessionData'; # provides $self->user_profile
use namespace::clean -except => 'meta';
# passed in from LIMS::model as my $model = $package->new(%args):
has _lims_db => ( is => 'ro', isa => 'LIMS::DB', required => 1 );
has sql_lib => ( is => 'ro', isa => 'SQL::Library', lazy_build => 1 );
__PACKAGE__->meta->make_immutable;
use LIMS::Local::Debug;
use LIMS::Local::Utils;
use DBIx::Simple;
use SQL::Library;
use IO::All;
use Data::Dumper;
# return LIMS::DB object passed in from LIMS::model():
sub lims_db { return shift->_lims_db }
# return LIMS config settings:
sub lims_cfg { LIMS::Local::Config->instance; }
#-------------------------------------------------------------------------------
sub get_objects {
my $self = shift;
my $class = shift; # scalar
my $args = shift || {}; # optional hashref, passed straight to Manager
my $rows = Rose::DB::Object::Manager->get_objects(
%$args,
object_class => 'LIMS::DB::' . $class,
);
return $rows;
}
#-------------------------------------------------------------------------------
sub get_objects_with {
my $self = shift;
my $args = shift; # hashref of keys = class & with
my $rows = Rose::DB::Object::Manager->get_objects(
require_objects => $args->{with},
object_class => 'LIMS::DB::' . $args->{class},
);
return $rows;
}
#-------------------------------------------------------------------------------
sub get_meta {
my $self = shift;
my $class = shift; # scalar
my $object_class = 'LIMS::DB::' . $class;
return $object_class->new->meta;
}
#-------------------------------------------------------------------------------
sub get_objects_count {
my $self = shift;
my $class = shift; # scalar
my $args = shift || {}; # optional hashref, passed straight to Manager
my $count = Rose::DB::Object::Manager->get_objects_count(
%$args,
object_class => 'LIMS::DB::' . $class,
);
return $count;
}
#-------------------------------------------------------------------------------
sub get_objects_iterator {
my $self = shift;
my $class = shift; # scalar
my $args = shift || {}; # optional hashref, passed straight to Manager
my $iterator = Rose::DB::Object::Manager->get_objects_iterator(
%$args,
object_class => 'LIMS::DB::' . $class,
);
return $iterator;
}
#-------------------------------------------------------------------------------
sub lims_dbix {
my $self = shift;
my $dbh = $self->lims_db->dbh;
my $dbix = DBIx::Simple->new($dbh);
return $dbix;
}
#-------------------------------------------------------------------------------
sub time_now {
my $self = shift;
return LIMS::Local::Utils::time_now; # considers BST
}
#-------------------------------------------------------------------------------
# generic update method - uses insert_or_update(), and will update record if 'id'
# supplied, otherwise insert new. Assumes any unique_key(s) has passed validation
# check & belongs to record being edited. Expects hashref with keys 'class' & 'data':
sub update_object {
my $self = shift;
my $args = shift; # $self->debug( $args );
my $class = $args->{class};
my $data = $args->{data};
my $object_class = 'LIMS::DB::' . $class;
my $o = $object_class->new();
my %args = ( data => $data, obj => $o );
# get form_params for specimens table into specimen object:
$self->populate_object_with_form_data(\%args);
#$self->set_rose_debug(1);
eval {
$o->insert_or_update( changes_only => 1 ); # doesn't do 'changes_only'
};
#$self->set_rose_debug(0);
return $@ if $@;
}
#-------------------------------------------------------------------------------
# used in validation_models to check uniqueness of column value
# expects hashref of args: class_name, column_name & column_value
sub get_object_by_param {
my $self = shift;
my $args = shift; # $self->debug($args);
my $class = $args->{class_name};
my %query = ( $args->{column_name} => $args->{column_value} );
my $object_class = 'LIMS::DB::'.$class;
#$self->set_rose_debug(1);
my $o = $object_class->new(%query)->load(speculative => 1);
#$self->set_rose_debug(0);
return $o;
}
#-------------------------------------------------------------------------------
# accepts hash(ref) of object to be populated, and submitted form_params
# and populates object with form_params - returns nothing:
sub populate_object_with_form_data {
my $self = shift;
my $args = shift; # $self->debug($args);
my $data = $args->{data};
my $obj = $args->{obj};
my @cols = $obj->meta->column_names;
# foreach table col:
foreach my $col (@cols) {
# value = corresponding form_param value:
my $val = $data->{$col};
# populate object accessor with value:
$obj->$col($val);
}
}
#-------------------------------------------------------------------------------
sub set_rose_debug {
my ($self, $switch) = @_;
$Rose::DB::Object::Debug =
$Rose::DB::Object::Manager::Debug
= $switch || 0; # zero probably not captured in $switch ??
}
#-------------------------------------------------------------------------------
sub debug {
my ($self, $str) = @_;
warn Dumper $str;
DEBUG($str);
}
#-------------------------------------------------------------------------------
sub _build_sql_lib {
my $self = shift;
my $path_to_app_root = $self->lims_cfg->{path_to_app_root};
# my $sql_lib
# = new SQL::Library( { lib => "$path_to_app_root/src/lib/library.sql" } );
# can only handle multiple sql libraries as strings:
my @libs
= map { io( sprintf '%s/src/lib/%s.sql', $path_to_app_root, $_ )->slurp }
qw(library local);
my $sql_lib = new SQL::Library( { lib => \@libs } ); # warn Dumper $sql_lib->elements;
return $sql_lib;
}
1;