*
  • $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 ?>