#!/usr/local/bin/perl
#
# Table
#
# Base class for all tables
#
# Author: Jennifer Liddle (js10)
#
# $Id: Table.pm,v 1.9 2007/01/30 12:04:16 js10 Exp $
#
# $Log: Table.pm,v $
# Revision 1.9  2007/01/30 12:04:16  js10
# Added an optional 'sessionId' paramater
#
# Revision 1.8  2006/09/15 17:39:32  js10
# emegency quick fix
#
# Revision 1.7  2006/09/15 09:36:54  js10
# Added the exists() method
#
# Revision 1.6  2006/06/27 17:18:17  js10
# minor bug fix in roleId2email
#
# Revision 1.5  2006/06/27 16:39:02  js10
# Optimised by moving virtualSqlLib()s into Tapir.sql_lib
#
# Revision 1.4  2006/06/26 09:27:32  js10
# moved common code into Table.pm
#
# Revision 1.3  2006/06/08 15:39:24  js10
# Added rdrequest and replace 'die' with 'confess'
#
# Revision 1.2  2006/05/12 15:20:56  js10
# Replace full pathname in status tables with base filename
#
# Revision 1.1.1.1  2006/05/12 08:47:19  js10
# Initial import
#
#

package Tapir::Table;

use strict;
use warnings;

=head1 NAME

Tapir::Table

=head1 SYNOPSIS

for documentation see http://intweb.sanger.ac.uk/Teams/Team71/Prod_sw_group/PSGDocs/Tapir

=cut

use SqlEngine2;
use File::Basename;
use Carp;
our $AUTOLOAD;

#
# Constructor
#
sub new 
{
	my $class = shift;
	my $self = {};
	bless($self, $class);
	$self->_initTable(@_);
	return $self;
}

#
# Initialise dbh and SqlEngine2
#
sub _initTable
{
	my $self = shift;
	$self->{dbh} = shift;
	confess "dbh not specified" unless ($self->{dbh} && $self->{dbh} =~ /DBI::db=HASH/);
	$self->{sessionId} = shift;
	$self->{sessionId} ||= $$;	# default to PID
	$self->{se} = new SqlEngine2();
	$self->{se}->loadSqlLib(['Tapir/Tapir']);
	$self->{Record} = {};
	my @prog = fileparse($0,'');
	$self->{Program} = $prog[0];
	$self->{exists} = 0;
}

#
# Handle the get... and set... accessor methods using an autoload function
#
sub AUTOLOAD
{
	my ($self, $v) = @_;
	my ($operation, $field);

	return if $AUTOLOAD =~ /DESTROY/;

	unless ( ($operation, $field) = ($AUTOLOAD =~ /::(get|set)([A-Z]\w+)$/) ) {
		confess "Invalid method call: $AUTOLOAD";
	}

	$field = lc $field;

	if ($operation eq 'get') {
		no strict 'refs';
		*{$AUTOLOAD} = sub { return $_[0]->{Record}->{$field} };
		confess "no such field: $field" if !exists $self->{Record}->{$field};
		return $self->{Record}->{$field};
	}

	if ($operation eq 'set') {
		no strict 'refs';
		*{$AUTOLOAD} = sub { $_[0]->{Record}->{$field} = $_[1] if defined $_[1]; 
		                     return $_[0]->{Record}->{$field}; 
		                   };
		$self->{Record}->{$field} = $v if defined $v;
		return $self->{Record}->{$field};
	}

	confess "No such method call: $AUTOLOAD";
}

#
# Read a record, including fieldnames, into a hash.
#
sub loadRecord
{
	my ($self, $id, $sql) = @_;

	my @record = $self->{se}->getRow($sql, [$id], $self->{dbh});
	$self->{exists} = scalar @record;
	my $fieldName = $self->{se}->getSthInfo($sql, 'NAME_lc', $self->{dbh});
	my $n = 0;
#	$self->{Record} = {};

	foreach my $v (@record) {
		$self->{Record}->{$fieldName->[$n]} = $v;
		$n++;
	}
}

#
# did the previous loadRecord() work?
#
sub exists
{
	my $self = shift;
	return $self->{exists};
}

#
# Load a dictionary table into a hash
#
sub loadDict
{
	my ($self, $sql) = @_;
	my %dict;

	my $a = $self->{se}->getAll($sql, [], $self->{dbh});
	foreach my $r (@$a) {
		$dict{$r->[0]} = $r->[1];
	}
	return \%dict;
}

#
# Look up an email address from a roleId
#
sub roleId2email
{
	my ($self, $roleId) = @_;
    my $email = $self->{se}->getRow('Tapir/Tapir::roleId2email', [$roleId], $self->{dbh});
    return $email;
}

#
# normalise status - verify and if a description, convert to a code
#
sub normaliseStatus
{
	my ($self, $newStatus) = @_;
	my $status;

    if (exists $self->{statusDict}->{$newStatus}) {
        $status = $newStatus;
    } else {
        # allow $newStatus to be the numberic code or the description
        foreach my $k (keys %{$self->{statusDict}}) {
            if ($self->{statusDict}->{$k} eq $newStatus) {
                $status = $k;
                last;
            }
        }
    }

	return $status;
}


1;
