elemento
Esta clase contiene las funciones principales de comunicación con la base de datos: Select, Update, Insert y Delete, además de dos funciones extras de uso interno como son SacarCampos y Recursiva (esta última no tiene un nombre muy adecuado, pero bueno, no sabía como llamarla) .
Esta clase no tiene constructor así que iré explicando método a método, pero debemos tener en cuenta que todo ello se encuentra entre las etiquetas:
Empezaremos por una sencilla, SacarCampos($tabla), que se encarga de obtener un array con el tipo de dato de cada campo de la tabla que pasamos como parametro.
Código php:
Ver originalfunction SacarCampos($tabla){
$consulta="SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '$tabla'";
$cn=new Conexion();
$res=$cn->Consulta($consulta);
$resultado[$row['COLUMN_NAME']]=$row['DATA_TYPE'];
}
return $resultado;
}
Del resto de métodos de la clase elemento me voy a centrar en el Update, pues utiliza la clase "CampoValor" y la clase "CondicionWhere" y a partir de él se pueden deducir el resto de métodos, pues estos serán inevitablemente, más sencillos.
Código php:
Ver originalfunction Update($camposvalores, $condicion){ // El parametro $camposvalores es un array de CampoValor
$tabla=$this->tabla;
if ($camposvalores!="" && $tabla!="") //Comprobamos que los datos sean correctos
{
$bdd_campos=$this->SacarCampos($tabla); // Obtenemos el array con el tipo de dato de los campos
$consulta = "UPDATE $tabla SET "; // $consulta será la cadena que finalmente lanzaremos contra la base de datos
foreach($camposvalores as $c){ // Recorremos el array de $camposvalores
$consulta.=$c->campo."="; // Añadimos a la cadena de la consulta el campo y el operador de asignacion
switch($bdd_campos[$c->campo]) // Comprobamos el tipo de dato para dcidir si ponemos comillas ( ' ) o no
{
case "char":
case "varchar":
case "date":
case "tinytext":
case "tinyblob":
case "text":
case "blob":
case "mediumtext":
case "mediumblob":
case "longtext":
case "longtext":
case "datetime":
$consulta.="'".$c->valor."', ";
break;
default:
$consulta.=$c->valor.", ";
break;
}
}
if ($condicion !=null){ // Si le pasamos condiciones...
$consulta=substr($consulta, 0, strlen($consulta)-2)." WHERE "; $cadena=$this->Recursiva($condicion); //Llamamos a la función "Recursiva" y obtenemos el valor de retorno
$consulta.=$cadena; // Lo añadimos a la cadena de consulta y Violá!
}
$cn=new Conexion();
return $cn->Consulta($consulta);
}
Vale, una vez hemos explicado estos métodos, solo nos queda hacerlo con el método "Recursiva", que aunque no es muy extenso, a mi me parece el más complicade de implementar y de explicar, y es precisamente como su nombre indica, por tratarse de una
función recursiva. No sé si es que son de lo más complicado de asumir/entender de la programación o simplemente a mi se me atraviesan especialmente, pero lo cierto es que tuve verdaderos problemas para crearla.
Código php:
Ver originalfunction Recursiva($condicion){ // el parametro $condicion puede ser un objeto CondicionWhere o una cadena y lo comprobamos en el siguiente if
if(strlen($condicion->parametro1)>0){ // Si se trata de un objeto CondicionWhere... $cadena.="("; // Añadimos el paréntesis de apertura para establecer la prioridad
$cadena.=$this->Recursiva($condicion->parametro1); //La función se llama a si misma para profundizar en el "parametro" del CondicionWhere.
// Para tenerlo mas o menos claro, construimos mentalmente $cadena.
// Hasta este momento $cadena vale esto: "(", si resulta que 4l "parametro1" de este CondicionWHERE
// resulta ser una cadena, irá por el else y $cadena pasará a valer "(NombreDelCampo".
// A continuación dejará un espacio y hará lo mismo con "operador", que irá por el else.
// igual con el "parametro2" de forma que al final la $cadena nos queda así (imaginemos que el operador es "=" ): "(NombreDelCampo = Valor)".
// Si se tratara de condiciones mas complejas, con unas dentro de otras, lo único que cambia es que se repetirá este proceso las veces necesarias construyendo finalmente la condición final.
$cadena.=" ";
$cadena.=$this->Recursiva($condicion->operador);
$cadena.=" ";
//Comprobar el campo
// Aquí comprobamos si hay que ponerle comillas ( ' ) al "parametro2".
$bdd_campos=$this->SacarCampos($this->tabla);
switch($bdd_campos[$condicion->parametro1])
{
case "char":
case "varchar":
case "date":
case "tinytext":
case "tinyblob":
case "text":
case "blob":
case "mediumtext":
case "mediumblob":
case "longtext":
case "longtext":
case "datetime":
$marca="'";
break;
default:
$marca="";
break;
}
$cadena.=$marca; // Si necesita comillas se las ponemos
$cadena.=$this->Recursiva($condicion->parametro2);
$cadena.=$marca; // Si necesita comillas se las ponemos
$cadena.=")";
}
else{
$cadena.="$condicion";
}
return $cadena; // Devuelve la cadena para seguir construyéndola o para devolverla al método que llamó a este.
}
Llegado a este punto, para todo quede más claro, solo me falta mostrar la forma de usar estas clases y métodos.
Creamos una clase sencilla llamada "Lugar", creamos un objeto "Lugar", creamos el objeto CondicionWhere con varios CondicionWhere anidados y el array de CampoValor de asignación y llamamos a la función Update.
Código php:
Ver originalclass Lugar extends elemento
{
public $id;
public $nombre;
public $nombre_corto;
function Lugar(){
$this->tabla="Lugar";
}
}
$lug=new Lugar();
$con1=new CondicionWhere("nombre", "Can%", "LIKE");
$con2=new CondicionWhere("nombre_corto", "CAN");
$con3=new CondicionWhere("nombre_corto", "CNT");
$con4=new CondicionWhere($con2, $con3, "OR");
$con5=new CondicionWhere($con1, $con4, "AND");
$campos=array(new CampoValor
("nombre", "ValorNombre"),
new CampoValor("nombre_corto", "ValorNombreCorto"));
$lug->Update($campos, $con5);
El resultado es que el ORM envía a la base de datos MySql la consulta siguiente:
Cita: UPDATE Lugar SET nombre_corto='ValorNombreCorto' WHERE ((nombre LIKE 'Can%') AND ((nombre_corto = 'CAN') OR (nombre_corto = 'CNT')))
No sé si he logrado explicarme correctamente, pero he de decir que yo mismo me pierdo al intentar seguir el camino de la aplicación cuando llega a esta función recursiva. El caso es que funciona correctamente después de muchas pruebas y modificaciones.
Si a alguien le parece interesante y quiere utilizar este código puede hacerlo y si desea tener el código completo (con los métodos Select, Insert y Delete) solo tiene que mandarme un correo electrónico o pedirlo en los comentarios y se lo enviaré con mucho gusto, igualmente si alguien tiene alguna duda o sugerencia sobre esto, puede ponerla también en los comentarios.
Un saludo