#!/usr/bin/perl

# --------------------------------------------------------------
# Prontus CMS
# http://www.prontus.cl
# by Altavoz.net
#
# licensed under LGPL license.
# http://www.prontus.cl/license.html
# --------------------------------------------------------------

#-------------------------------COMENTARIO GLOBAL---------------
#---------------------------------------------------------------
# PROPOSITO.
#-----------
# Rutinas para acceso generico a bases de datos via DBI.
# Para utilizar DBI, aparte de Perl se requieren los sgtes. paquetes :
# 1) DBI.
# 2) DBD-Mysql u otro específico para la BD que se desa accesar.
#---------------------------------------------------------------

#---------------------------------------------------------------
# DECLARACIONES GLOBALES.
#------------------------

package glib_dbi_03;
use DBI;
use utf8;
use strict;

#---------------------------------------------------------------
# SUB-RUTINAS.
#---------------------------------------------------------------

#-------------------------------------------------------------------------#
# Ejecuta una sentencia sql.
# Parametros:
# 0)base de datos abierta
# 1)sentencia sql
# Retorna: handle de salida de la sentencia
sub ejecutar_sql {

    my $dbh = $_[0];
    my $sql = $_[1];

    if (!ref($dbh)) {
        return '';
    }

    my $tab_output = $dbh->prepare($sql)  or  print STDERR "Error: $sql\n" . $dbh->errstr;
    $tab_output->execute() or  print STDERR "Error: $sql\n" . $dbh->errstr;
    print STDERR "SQL Error: [$sql]\n" if ($dbh->errstr);
    return $tab_output;
}

#-------------------------------------------------------------------------#
# Inserta registro y devuelve nuevo ID.

# Parametros :
# 0) base de datos abierta
# 1) sentencia insert
# Retorna : Nuevo ID.
sub insert_dev_id_param {
    my $dbh = shift;
    my $sql = shift;
    my $ref_params = shift;

    my $sth = $dbh->prepare($sql) or print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->execute(@$ref_params) or print STDERR "Error: ". $dbh->errstr."\n";
    $sth->finish;

    $sth = $dbh->prepare('select last_insert_id()') or print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->execute() or print STDERR "Error: ". $dbh->errstr."\n";
    my @nuevo_id = $sth->fetchrow_array;
    $sth->finish;

    return $nuevo_id[0];
}

#-------------------------------------------------------------------------#
# Inserta registro y devuelve nuevo ID.
# Parametros :
# 0) base de datos abierta
# 1) sentencia insert
# Retorna : Nuevo ID.
sub insert_dev_id { # 01.1

    my $dbh = $_[0];
    my $sql = $_[1];
    my ($res, @nuevo_id);

    $res = $dbh->do($sql);
    print STDERR "SQL Error: [$sql][".$dbh->errstr."]\n" if ($dbh->errstr);

    $sql = 'select last_insert_id()';
    $res = &ejecutar_sql($dbh, $sql);
    @nuevo_id = $res->fetchrow_array;
    $res->finish;

    return $nuevo_id[0];
}

#-------------------------------------------------------------------------#
# Averigua si una col existe.
# Si existe, retorna el nombre de la col.
# Si no existe, retorna ''
sub check_table_column {
    my ($dbh, $tabla, $colname, $coldef) = @_;
    my $sql = "SHOW COLUMNS FROM $tabla LIKE '$colname'";
    my $nom;
    my ($type, $null, $key, $default, $extra);
    my $res = &ejecutar_sql_bind($dbh, $sql, \($nom, $type, $null, $key, $default, $extra));
    $res->fetch;
    $res->finish;

    # crear columna si no existe y si es q viene la def del campo
    if (!$nom) {
        if ($coldef) {
            $dbh->do("ALTER TABLE $tabla ADD $colname $coldef") || return 0;
            return 1;
        } else {
            return 0;
        }
    } else {
        return $nom;
    }
}

#-------------------------------------------------------------------------#
# Averigua si una col existe.
# Si existe, retorna el nombre de la col.
# Si no existe, retorna ''
sub get_table_column_def {
    my ($dbh, $tabla, $colname) = @_;
    my $sql = "SHOW COLUMNS FROM $tabla LIKE '$colname'";
    my $nom;
    my ($type, $null, $key, $default, $extra);
    my $res = &ejecutar_sql_bind($dbh, $sql, \($nom, $type, $null, $key, $default, $extra));
    $res->fetch;
    $res->finish;

    # no existe columan retorna 0
    if (!$nom) {
        return 0;

    } else {
        return (1, $nom, $type, $null, $key, $default, $extra);
    }
}

#-------------------------------------------------------------------------#
# Revisa si la tabla existe
sub existe_tabla {
    my $dbh = $_[0];
    my $tabla = $_[1];

    my $nom = 0;
    my $sql = "show tables";
    my $salida = &ejecutar_sql_bind($dbh, $sql, \($nom));
    while ($salida->fetch) {
        if ($nom eq $tabla) {
            $salida->finish;
            return $nom;
        }
    }
    $salida->finish;
    return '';
}

#-------------------------------------------------------------------------#
# ejecuta una sentencia sql y devuelve su handler.
# Param entrada:
#  0) descriptor de la base de datos abierta.
#  1) sentencia SQL propiamente tal.
#  2) nombres de las variables asociadas a los campos.
# retorno:
#  0) descriptor de la respuesta. (Usar solamente fetch para cargar las variables con las filas siguientes.
sub ejecutar_sql_bind {
    my ($dbh) = shift;
    my ($sql) = shift;
    my (@var) = (@_);
    my ($sth);

    $sth = $dbh->prepare($sql) or  print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->execute or print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->bind_columns(undef, (@var)) or print STDERR "Error: ".$dbh->errstr ."\n";
    print STDERR "SQL Error: [$sql]\n" if ($dbh->errstr);
    return($sth);
}

#-------------------------------------------------------------------------
# Ejecuta una sentencia sql parametrizada y devuelve su handler.
# Param entrada:
#  0) descriptor de la base de datos abierta.
#  1) sentencia SQL parametrizada.
#  2) ref a array con nombres de los parámetros a usar en la sentencia SQL.
#  3) ref a array con nombres de las variables asociadas a los campos de respuesta.
# retorno:
#  0) descriptor de la respuesta. (Usar solamente fetch para cargar las variables con las filas siguientes.)
sub ejecutar_sql_bind_param {
    my $dbh = shift;
    my $sql = shift;
    my $ref_params = shift;
    my @ref_vars = @_;


    my $sth = $dbh->prepare($sql) or print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->execute(@$ref_params) or print STDERR "Error: ". $dbh->errstr."\n";
    $sth->bind_columns(undef, @ref_vars) or print STDERR "Error: ". $dbh->errstr."\n";
    print STDERR "SQL Error: [$sql]\n" if ($dbh->errstr);
    return($sth);
}

#-------------------------------------------------------------------------
# Ejecuta una sentencia sql parametrizada y devuelve su handler.
# Param entrada:
#  0) descriptor de la base de datos abierta.
#  1) sentencia SQL parametrizada.
#  2) ref a array los parámetros a usar en la sentencia SQL.
# Retorna : handle de salida de la sentencia
sub ejecutar_sql_param {
    my $dbh = shift;
    my $sql = shift;
    my $ref_params = shift;

    my $sth = $dbh->prepare($sql) or print STDERR "Error: ".$dbh->errstr ."\n";
    $sth->execute(@$ref_params) or print STDERR "Error: ".$dbh->errstr ."\n";
    print STDERR "SQL Error: [$sql]\n" if ($dbh->errstr);
    return($sth);
}

# Revisa si la tabla existe
sub check_index_table {
    my ($dbh, $table, $column, $index) = @_;

    my $sql = "show index from $table where Column_name='$column'";
    my $salida = &ejecutar_sql($dbh, $sql);
    my $row = $salida->fetchrow_hashref;
    $salida->finish;
    if ($index && $row->{'Key_name'} eq $index) {
        return 1;
    } elsif ($row->{'Column_name'} eq $column) {
        return 1;
    } else {
        return 0;
    }
}

1;
