#!/usr/bin/perl
# -----------------------------------------------------------------------------
# TWC
# Treuwert-Computer GmbH
# Schloßbergring 9
# 79098 Freiburg
#
# Author: Klaus Reger <K.Reger@twc.de>
#
# -----------------------------------------------------------------------------
# Program-Data
# -----------------------------------------------------------------------------
# Project  :
# System   :
# Program  :
# Module   : $RCSfile: Pg.pm,v $
# Version  : $Revision: 1.3 $
# Date     : $Date: 2002/03/15 10:37:17 $
# State    : $State: Exp $
#
# Description:
#   This module handles all the things of WWWdb, which have
#   to do with DbSessions
#
# Change-log (See at end of this file)
#
# --- Known Bugs -------------
# please look at the BUGS-File
# --- TODO -------------------
# please look at the TODO-File
# ----------------------------------------------------------------------------
# use DBI;
# use Data::Dumper;
# use Date::Calc qw(:all);
# use Time::Local;

use strict;
use DBI;

package DbSession;

use vars qw(%hDatatypesGL 
            @lDbDateScanFormats 
            @lDbDatetimeScanFormats 
            @lDbTimeScanFormats);

%hDatatypesGL = 
    ('1042' => DBI::SQL_VARCHAR,    # bpchar
     '25'   => DBI::SQL_VARCHAR,    # bpchar (Pg: text)
     '1700' => DBI::SQL_FLOAT,      # float4
     '700'  => DBI::SQL_FLOAT,      # float4
     '23'   => DBI::SQL_INTEGER,    # int4
     '26'   => DBI::SQL_INTEGER,    # int4 (Pg: oid)
     '21'   => DBI::SQL_SMALLINT,   # int2
     '700'  => DBI::SQL_FLOAT,      # float4
     '701'  => DBI::SQL_REAL,       # float8
     '20'   => DBI::SQL_INTEGER,    # int8
     '1082' => DBI::SQL_DATE,       # date
     '1184' => DBI::SQL_TIMESTAMP,  # timestamp
     '1083' => DBI::SQL_TIME,       # time
     '1296' => DBI::SQL_TIMESTAMP,  # timestamp
     '1043' => DBI::SQL_VARCHAR,    # varchar
     '30'   => DBI::SQL_INTEGER,    # oid_vector
    ); 

@lDbDatetimeScanFormats = ("%Y-%m-%d %H:%M:%S%z?",
                           "%Y-%m-%d",
                           "%a +%b +%e +%H:%M:%S +%Y.*");
@lDbDateScanFormats     = ("%Y-%m-%d",
                           "%a +%b +%e +%H:%M:%S +%Y.*");
@lDbTimeScanFormats     = ("%H:%M:%S%z?");

# --- PostgreSQL -------------------------------------------------------------

sub _CreateDataSource
# ----------------------------------------------------------------------------
{
   my $hSelfPI   = shift;

   $hSelfPI->{"DataSource"} =
       sprintf("dbi:Pg" .
               "(RaiseError=>%d, PrintError=>%d, AutoCommit=>%d)" .
               ":dbname=%s%s",
               $hSelfPI->{"RaiseError"},
               $hSelfPI->{"PrintError"},
               $hSelfPI->{"AutoCommit"},
               $hSelfPI->{"DbName"},
               ($hSelfPI->{"DbHost"}?
                ";host=" . $hSelfPI->{"DbHost"}:
                ""));
   $ENV{"PGDATESTYLE"}  = "ISO";

   return $hSelfPI->{"DataSource"};

}

sub DateFromDb($$;$)
# ----------------------------------------------------------------------------
{
   my $hSelfPI   = shift;
   my $cFieldPI  = shift;
   my $cFormatPI = shift;

   my $cResult = &DbSession::PrintDate
       ($cFormatPI || $hSelfPI->getDatePrintFormat(),
        &DbSession::ScanDate($cFieldPI, @lDbDatetimeScanFormats)) ||
            $cFieldPI;

    return $cResult;

}

sub DateToDb($$)
# ----------------------------------------------------------------------------
{
    my $hSelfPI  = shift;
    my $cFieldPI = shift;
    
    my $cResult = &DbSession::PrintDate
        ($lDbDatetimeScanFormats[0],
         &DbSession::ScanDate($cFieldPI,
                              @{$hSelfPI->getDateScanFormats()})) ||
                                  $cFieldPI;
    
    # this is because Postgres does not allow empty values
    $cResult = "1-1-1900 00:00:00"
        unless $cResult;
    
    return $cResult;
    
}


# --- Convert datetime-fields from form to db ---------------------------------
sub SQL_DATE_Form2Db ($$)
{
    my $hSelfPI  = shift;
    my $cFieldPI = shift;
    
    my $cResult = &DbSession::PrintDate
        ($lDbDateScanFormats[0],
         &DbSession::ScanDate($cFieldPI,
                              @{$hSelfPI->getDateScanFormats()})) ||
                                  $cFieldPI;
    
    return $cResult;
}


# --- Convert time-fields from db to form ---------------------------------
sub SQL_DATE_Db2Form ($$)
{
    my $hSelfPI  = shift;
    my $cFieldPI = shift;
    
    my $cResult = &DbSession::PrintDate
        ($hSelfPI->getDatePrintFormat(),
         &DbSession::ScanDate($cFieldPI, @lDbDateScanFormats)) ||
             $cFieldPI;
    
    return $cResult;
}



# --- Convert abstime-fields from form to db ---------------------------------
sub SQL_ABSTIME_Form2Db($$)
{
    return &DateToDb(shift, shift);
}



# --- Convert abstime-fields from db to form ---------------------------------
sub SQL_ABSTIME_Db2Form($$)
{
    return &DateFromDb(shift, shift, shift);
}



# --- Convert datetime-fields from form to db ---------------------------------
sub SQL_DATETIME_Form2Db ($$)
{
    return &DateToDb(shift, shift);

}

# --- Convert datetime-fields from db to form ---------------------------------
sub SQL_DATETIME_Db2Form ($$$)
{
    return &DateFromDb(shift, shift, shift);
}


# --- Convert datetime-fields from form to db ---------------------------------
sub SQL_TIMESTAMP_Form2Db($$$)
{
    return &DateToDb(shift, shift);
}

# --- Convert datetime-fields from db to form ---------------------------------
sub SQL_TIMESTAMP_Db2Form ($$$)
{
    return &DateFromDb(shift, shift, shift);
}



# --- Convert float4-fields from form to db ---------------------------------
sub SQL_FLOAT4_Form2Db ($$)
{
    my $hSelfPI   = shift;
    my $cFieldPI = shift;

    my $cResult;

    ($cResult = $cFieldPI) =~ s/,/./g;

    return $cResult;
}


# --- Convert float4-fields from db to form ---------------------------------
sub SQL_FLOAT4_Db2Form ($$)
{
    my $hSelfPI   = shift;
    my $cFieldPI = shift;

    my $cResult;

    ($cResult = $cFieldPI) =~ s/\./,/g;

    $cResult = sprintf "%.2f", $cResult
        if($cResult =~ m/(,\d{0,2})$/);

    return $cResult;
}



# --- Convert float8-fields from form to db ---------------------------------
sub SQL_FLOAT8_Form2Db($$)
{
    return &SQL_FLOAT4_Form2Db(shift, shift);
}



# --- Convert float8-fields from db to form ---------------------------------
sub SQL_FLOAT8_Db2Form($$)
{
    return &SQL_FLOAT4_Db2Form(shift, shift);
}


# --- Map internal PostgreSQL-Datatypes to DBI-standard
sub MapDatatype($)
{
    my $iDatatypePI = shift;
    my $iResult;

    $iResult = (defined $hDatatypesGL{$iDatatypePI}?
                $hDatatypesGL{$iDatatypePI}:
                $iDatatypePI);

    die "Undefined type $iResult"
        if $iResult > 20;
    
    return $iResult;
}


1;

