*
$obj_conexion - El objeto de conexión con el que trabaja.
* $obj_errorConexion - Referencia al objeto de error global
*
*
* @version $Id: IgepConexion.php,v 1.57 2008-06-09 10:23:10 gaspar Exp $
* @author David:
* @author Keka:
* @author Vero:
* @author Raquel:
* @author Toni:
* @package gvHIDRA
*/
class IgepConexion {
/**
* objeto conexion
*
* @var object obj_conexion
*/
var $obj_conexion;
/**
* variable de error
*
* @var object obj_errorConexion
*/
var $obj_errorConexion;
/**
* variable de que contiene la descripción del dsn al que se conecta
*
* @var array v_dsn
*/
var $v_dsn;
/**
* Constructor. Recibe como parámetro un array con la definición
* del dsn.
*
* @access public
* @param array $dsn
*/
function IgepConexion($dsn) {
//Cogemos la referencia de la variable de error global
global $g_error;
$this->obj_errorConexion = & $g_error;
//Realizamos la conexión
$this->v_dsn = $dsn;
$this->obj_conexion = $this->conectar($dsn);
}
//destructor
function _destruct() {
$this->desconectar();
}
/**
* Realiza la conexión a la base de datos especificada
*
* @access public
* @return object
*/
private function conectar($dsn){
IgepDB::preConexion($dsn);
$options = array(
'portability' => MDB2_PORTABILITY_NONE,
);
$res = MDB2::connect($dsn,$options);
if (PEAR::isError($res)) {
$this->obj_errorConexion->setError("IGEP-6",'IgepConexion.php',"conectar",$res);
} else {
IgepDB::postConexion($dsn,$res);
//Finalmente marcamos el fetchMode por defecto
$res->setFetchMode(MDB2_FETCHMODE_ASSOC);
}
return $res;
}// Fin de conectar
/**
* Realiza la desconexión a la base de datos a la que actualmente
* se está conectado.
*
* @access public
*/
private function desconectar(){
if(isset($this->obj_conexion)) {
$res = $this->obj_conexion->disconnect();
if (PEAR::isError($res))
$this->obj_errorConexion->setError("IGEP-7",'IgepConexion.php',"desconectar",$res);
}
}// Fin de desconectar
/**
* Devuelve el objeto conexión al que se está conectado.
*
* @access public
* @return object
*/
public function getConexion(){
return $this->obj_conexion;
}//Fin de getConexion
/**
* Devuelve el dsn de la conexión.
*
* @access public
* @return array
*/
public function getDsn(){
return $this->v_dsn;
}//Fin de getDsn
/**
* Empieza una transacción (BEGIN) en la conexión a la que
* está apuntando.
*
* @access public
*/
public function empezarTransaccion()
{
//Debug:Indicamos que ejecutamos la consulta
IgepDebug::setDebug(DEBUG_IGEP,'Empezamos transacción.');
$res = IgepDB::empezarTransaccion($this->v_dsn,$this->obj_conexion);
if (PEAR::isError($res))
$this->obj_errorConexion->setError("IGEP-8",'IgepConexion.php',"empezarTransaccion",$res);
}//Fin de empezarTransaccion
/**
* Finaliza una transacción (COMMIT o ROLLBACK) en la conexión a la que
* está apuntando. Recibe un parámetro que indica si el procesado de las
* diferentes operaciones que se han realizado ha concluido satisfactoriamente
* o no. Dependiendo de ello se realizará el COMMIT o el ROLLBACK. Dicho
* parámetro es $error
*
* - 0. No ha habido ningún error en el proceso. Realizamos COMMIT
* - 1. Ha habido algún error durante el proceso. Realizamos ROLLBACK
*
*
* @access public
* @param integer $error
*/
public function acabarTransaccion($error){
//Debug:Indicamos que ejecutamos la consulta
IgepDebug::setDebug(DEBUG_IGEP,'Acabamos transacción con '.$error);
$res = IgepDB::acabarTransaccion($this->v_dsn,$this->obj_conexion,$error);
if (PEAR::isError($res))
$this->obj_errorConexion->setError("IGEP-9",'IgepConexion.php',"acabarTransaccion",$res);
}//Fin de acabarTransaccion
/**
* Método encargado de construir las WHERE de las consultas.
* @access private
*/
public function construirWhere($v_datos,$str_where){
//Esta función construye una WHERE igualando los valores con los nombres de los campos.
if (isset($v_datos)){
if($str_where!='')
$inicio_condicion=' OR (';
else
$inicio_condicion=' (';
$str_condicion='';
foreach($v_datos as $prop => $val) {
if ($str_condicion!='') {
$str_condicion.=' AND ';
}
$str_condicion.=$prop;
if (gettype($val)=='string') {
if($val!='')
$str_condicion.="='".$val."'";
else
$str_condicion.=' is null';
}
else {
if($val!='')
$str_condicion.='='.$val;
else
$str_condicion.=' is null';
}
}//FIN foreach
if(trim($str_condicion)!='')
$str_where.=$inicio_condicion.$str_condicion.')';
}
return $str_where;
} //Fin de construirWhere
/**
* Método encargado de construir las WHERE de las consultas incluyendo las condiciones de busqueda que ha seleccionado el programador a partir del parámetro gint_tipoConsulta
* @access private
*/
public function construirWhereConLike($v_datos,$str_where,$tipoConsulta){
/*Dependiendo del valor de la variable global gint_tipoConsulta realiza una construcción de la Where u otra.Los tipos son:
- 0. Se contruye igualando los campos a los valores.
- 1. Se construye con like y comodines para cada campo.
- 2. Por defecto, se contruye con like sólo si el usuario ha especificado comodines.
*/
//Accedemos a la varible global que nos dice que tipo de Consulta debemos realizar para toda la aplicación.
if($tipoConsulta==0)
return $this->construirWhere($v_datos,$str_where);
else
//Construimos la Where
if (isset($v_datos)){
if($str_where!='')
$inicio_condicion =' OR (';
else
$inicio_condicion =' (';
$str_condicion='';
foreach($v_datos as $prop => $val){
if($val!=''){
if ($str_condicion!=''){
$str_condicion.=' AND ';
}
if($tipoConsulta==3)
$str_condicion.="lower(".$prop.")";
else
$str_condicion.=$prop;
if($tipoConsulta==2){
//Son 3 iguales porque si colocamos 2 no distinguimos entre algo que esté en la posición 0 y el false
if((strpos($val,'%')===false) and (strpos($val,'_')===false)){
if (gettype($val)=='string')
$str_condicion.="='".$val."'";
else
$str_condicion.='='.$val;
}
else {
$str_condicion.=" LIKE '".$val."'";
}
}//Fin tipoConsulta == 2
else {
if($tipoConsulta==3)
$str_condicion.=" LIKE ".IgepDB::unDiacritic($this->getDsn(),"lower('%".$val."%')");
else
$str_condicion.=" LIKE '%".$val."%'";
}
}
}//FIN foreach
if(trim($str_condicion)!='')
$str_where.=$inicio_condicion.$str_condicion.')';
}
return $str_where;
}//Fin de construirWhereConLike
/**
* Método encargado de, dadas una serie de cadenas, componerlas para crear una única
* cadena para la where de una SQL.
* @acces private
* @param array $v_cadenas Array que contiene las diferentes cadenas que componen la WHERE
* @return string
*/
public function combinarWhere($v_cadenas){
$str_where = '';
foreach($v_cadenas as $cadena){
if(trim($cadena)!=''){
if ($str_where!='')
$str_where.= ') AND ';
$str_where.='('.$cadena;
}
}
if($str_where!='')
$str_where=' WHERE '.$str_where.')';
return $str_where;
}
/**
* Método encargado de construir el limit para las consultas
* @access private
*/
function construirLimite(& $str_where,$int_limiteConsulta=100){
if(is_int($int_limiteConsulta)){
$limite = IgepDB::obtenerLimit($str_where, $this->v_dsn, $int_limiteConsulta);
}
return $limite;
}//Fin de construirLimite
/**
* Dada una una consulta realiza la SELECT correspondiente.
*
* @access public
* @param string $str_select
* @return object
*/
public function consultar($str_select,$tipo=NULL){
//Debug:Indicamos que ejecutamos la consulta
IgepDebug::setDebug(DEBUG_IGEP,'IgepConexion: Ejecutamos consulta: '.$str_select);
if(!$this->obj_errorConexion->hayError()){
$resc = $this->obj_conexion->query($str_select);
if (PEAR::isError($resc)){
$this->obj_errorConexion->setError("IGEP-5",'IgepConexion.php',"consultar",$resc,$str_select);
return -1;
}
$res = $resc->fetchAll();
if (!is_null($tipo)) {
if (array_key_exists('DATATYPES',$tipo)) {
// convertimos los tipos a la estructura usada en this->v_descCamposPanel
// si es necesario
$datatypes = array();
foreach($tipo['DATATYPES'] as $clave=>$valor)
if (is_array($valor) and array_key_exists('tipo',$valor))
$datatypes[$clave] = $valor;
else
$datatypes[$clave] = array('tipo'=>$valor);
} else
$datatypes = null;
// dsn de donde provienen los datos
$a_dsn = $this->getDSN();
switch ($tipo['TYPE']) {
case NODO_NEGOCIO:
$res = ConfIgep::prepararNegocio($res, $datatypes, $a_dsn);
break;
case NODO_INTERFAZ:
$res = ConfIgep::prepararPresentacion($res, $datatypes, $a_dsn);
break;
case NODO_BD:
IgepDebug::setDebug(WARNING,'IgepConexion: Los datos no necesitan transformación');
break;
default:
IgepDebug::setDebug(ERROR,"IgepConexion: El tipo de nodo '".(is_null($tipo['TYPE']? 'NULO':$tipo['TYPE']))."' no existe");
}
}
return $res;
}
}
/**
* Dada una una consulta realiza la SELECT correspondiente.
*
* @access public
* @param string $str_select
* @return object
*/
public function operar($str_operar){
//Debug:Indicamos que ejecutamos la operacion
IgepDebug::setDebug(DEBUG_IGEP,'IgepConexion: Ejecutamos operación: '.$str_operar);
if(!$this->obj_errorConexion->hayError()){
$res = $this->obj_conexion->exec($str_operar);
if (PEAR::isError($res)){
$this->obj_errorConexion->setError("IGEP-11",'IgepConexion.php',"operar",$res,$str_operar);
return -1;
}
return $res;
}
}
/**
* Este método prepara los datos que se van a utilizar en una consulta/operación de la BD.
* Típicamente las comillas simples y las contrabarras en las cadenas de texto,
* las fechas y los decimales en los sistemas que tengan mascaras diferentes a las de IGEP (p.e. MySQL).
* Este método debe ser invocado por el usuario antes de realizar cualquier consulta/operacion a la BD
* para garantizar la portabilidad.
* Conversion de capa presentacion a capa datos
*
* @access public
* @param any $a_parametros
* @param any $a_tipo
* @return none
*/
public function prepararOperacion(& $a_parametros, $a_tipo=TIPO_CARACTER){
ConfIgep::setTransformErrors(array());
$transformer = new IgepTransformer(true);
$carbd = IgepDB::caracteresNumericos($this->getDsn());
$carconf = ConfIgep::caracteresNumericos();
$transformer->setDecimal($carconf['DECIMAL'],$carbd['DECIMAL'],$carconf['GROUP'],$carbd['GROUP']);
$fechabd = IgepDB::mascaraFechas($this->getDsn());
$fechaconf = ConfIgep::mascaraRepresentacionFechas();
$transformer->setDate($fechaconf,$fechabd);
/*Si el sistema tiene activado los magic quotes no será necesario escapar los caracteres, en caso contrario gvHidra los escapa*/
if(get_magic_quotes_gpc()==0){
$transformer->setCharacter("'","''");
$transformer->setCharacter("\\","\\\\");
}
if (is_array($a_parametros)){
foreach ($a_parametros as $fila => $tupla){
foreach ($tupla as $campo => $valor){
$tipo_efectivo = (empty($a_tipo[$campo]['tipo'])? TIPO_CARACTER: ($a_tipo[$campo]['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo[$campo]['tipo']));
$a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $valor);
}
}
} elseif ($a_parametros!='' and $a_tipo!='') {
$tipo_efectivo = ($a_tipo==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo);
$a_parametros = $transformer->process($tipo_efectivo,$a_parametros);
}
ConfIgep::setTransformErrors($transformer->getTransformErrors());
}//Fin de prepararOperacion
//REVIEW: PARCHE 3 NIVELES DE DATOS
/********************************************************PARCHE PROVISIONAL********************************************************/
/*
* PARCHE: PARA QUE PODAMOS TENER DE FORMA TRANSITORIA LOS DATOS EN UN FORMATO OPERABLE POR EL USUARIO EN LOS PRE, POST Y ACCIONES DE INTERFAZ
* SE CREAN ESTOS DOS MÉTODOS PARA QUE, DE ESTE MODO, PODAMOS ESCAPAR PRIMERO LOS NÚMEROS Y LAS FECHAS, Y EN OTRO MÉTODO LAS CADENAS.
*
*
* ASI, PRIMERO UTILIZAMOS EL MÉTODO prepararOperacionNumerosFechas QUE DEJA LOS DATOS EN FORMATO PHP.
* UNA VEZ REALIZADOS LOS CAMBIOS POR EL USUARIO, ESCAPAMOS LAS CADENAS PARA DEJARLO EN FORMATO BD.
*
*/
public function prepararOperacionNumerosFechas(& $a_parametros, $a_tipo=TIPO_CARACTER){
ConfIgep::setTransformErrors(array());
$transformer = new IgepTransformer(true);
$carbd = IgepDB::caracteresNumericos($this->getDsn());
$carconf = ConfIgep::caracteresNumericos();
$transformer->setDecimal($carconf['DECIMAL'],$carbd['DECIMAL'],$carconf['GROUP'],$carbd['GROUP']);
$fechabd = IgepDB::mascaraFechas($this->getDsn());
$fechaconf = ConfIgep::mascaraRepresentacionFechas();
$transformer->setDate($fechaconf,$fechabd);
if(is_array($a_parametros)){
foreach ($a_parametros as $fila => $tupla){
foreach ($tupla as $campo => $valor){
$tipo_efectivo = (empty($a_tipo[$campo]['tipo'])? TIPO_CARACTER: ($a_tipo[$campo]['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo[$campo]['tipo']));
$a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $valor);
}
}
}
elseif ($a_parametros!='' and $a_tipo!='') {
$tipo_efectivo = ($a_tipo==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo);
$a_parametros = $transformer->process($tipo_efectivo,$a_parametros);
}
ConfIgep::setTransformErrors($transformer->getTransformErrors());
}//Fin de prepararOperacion
public function prepararOperacionCadenas(& $a_parametros, $a_tipo=TIPO_CARACTER){
$transformer = new IgepTransformer();
/*Si el sistema tiene activado los magic quotes no será necesario escapar los caracteres, en caso contrario gvHidra los escapa*/
if(get_magic_quotes_gpc()==0){
$transformer->setCharacter("'","''");
$transformer->setCharacter("\\","\\\\");
}
if (is_array($a_parametros)){
foreach ($a_parametros as $fila => $tupla){
foreach ($tupla as $campo => $valor){
$tipo_efectivo = (empty($a_tipo[$campo]['tipo'])? TIPO_CARACTER: ($a_tipo[$campo]['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo[$campo]['tipo']));
$a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $valor);
}
}
} elseif ($a_parametros!='' and $a_tipo!='') {
$tipo_efectivo = ($a_tipo==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo);
$a_parametros = $transformer->process($tipo_efectivo,$a_parametros);
}
}//Fin de prepararOperacion
/******************************************************** FIN PARCHE ********************************************************/
/**
* Transforma un numero de capa negocio a capa datos
*
* @access public
* @param any $a_num
* @return string
*/
function prepararNumero($a_num)
{
return ConfIgep::prepararDatos($a_num, TIPO_DECIMAL, $this->getDsn());
}
/**
* Transforma una fecha de capa negocio a capa datos
*
* @access public
* @param any $a_fecha
* @return string
*/
function prepararFecha($a_fecha)
{
return ConfIgep::prepararDatos($a_fecha, TIPO_FECHAHORA, $this->getDsn());
}
/**
* Este método devuelve el valor de una secuencia programada en la base de datos
* para la conexion actual
*
* @param nombreSecuencia string nombre de la secuencia en la BD
* @return integer
*/
public function calcularSecuenciaBD($nombreSecuencia){
$sql = IgepDB::obtenerSecuenciaBD($this->getDsn(),$nombreSecuencia);
IgepDebug::setDebug(DEBUG_IGEP,'IgepConexion: Calculamos secuencia BD: '.$sql);
$resc = $this->obj_conexion->query($sql);
if (PEAR::isError($resc)){
$this->obj_errorConexion->setError('IGEP-12','IgepConexion.php',"calcularSecuenciaBD",$resc);
return -1;
}
else{
$res = $resc->fetchAll();
return $res[0]['nextval'];
}
}
/**
* Este método calcula una secuencia compuesta por varios campos de la misma tabla.
*
* @param tabla string nombre de la tabla de la BD
* @param campoSecuencia string campo del que se quiere obtener la secuencia
* @param camposDependientes array contiene el nombre de los campos de los cuales va a depender la secuencia y sus valores. Estructura [nombreBD] = valor
* @param valorInicial integer Fija el valor inicial que devuelve calcularSecuencia en el caso de que no exístan tuplas en la tabla el valor por defecto es 1
* @return integer
*/
public function calcularSecuencia($tabla,$campoSecuencia,$camposDependientes, $valorInicial=1){
$i=0;
$where='';
foreach($camposDependientes as $campo => $valor){
if($where!='')
$where.=' AND ';
else
$where = 'WHERE ';
$where.=$campo."='".$valor."' ";
++$i;
}
$sql = "SELECT max($campoSecuencia) as \"secuencia\" FROM $tabla $where";
IgepDebug::setDebug(DEBUG_IGEP,'IgepConexion: Calculamos secuencia: '.$sql);
$resc = $this->obj_conexion->query($sql);
if(PEAR::isError($resc)) {
$this->obj_errorConexion->setError('IGEP-12','IgepConexion.php','calcularSecuencia',$resc);
return -1;
}
else {
$res = $resc->fetchAll();
if (($res[0]['secuencia']=='')||($res[0]['secuencia']==null)||(!isset($res[0]['secuencia'])))
return $valorInicial;
else
return ($res[0]['secuencia'] +1);
}
}//Fin de funcion calcularSecuencia
}//Fin clase IgepConexion
?>