No es un bug, es una característica no documentada

miércoles, 10 de diciembre de 2014

Entornos de desarrollo. PHPMyAdmin (II)

9:26 Posted by Inazio No comments
Seguimos con la práctica del post anterior.
El siguiente paso es instalar el codeblocks para escribir más comodamente en Linux, y también libmysqlclient-dev, una librería de desarrollo que es la que incluye <mysql.h>

Para instalarla, escribimos


Aparte de ello, necesitaremos otros servicios para conectarnos de forma remota, ya que por defecto la conexión no se permitirá.
Para ello, usaremos deb4free.net.

Nos vamos a http://www.db4free.net/signup.php y posteriormente confirmamos el mail que recibiremos en nuestra cuenta


Una vez confirmada, veremos esto



Vamonos a la terminal.

Debemos tener en cuenta que usaremos dos comandos para nuestros programas con mysql:

mysql_config --cflags
mysql_config --libs

En la siguiente imagen podemos ver, en la linea inferior de cada comando, a que corresponde su ejecución


Vamos a abrir el CodeBlocks y creamos un nuevo proyecto de aplicación de consola


Abrimos el main y añadimos al código la librería mysql


Ahora nos vamos, sobre el protecto, a Botón derecho - Build Options / Compiler Settings / Other options, y escribimos `mysql_config --cflags`


Nos vamos luego a Link Settings / Other linker options y escribimos `mysql_config --libs`, y aceptamos


Esto ya nos permitirá compilar correctamente nuestro código

Vamos a escribir nuestro primer código, uno que nos permitirá conocer la información de nuestro cliente mysql


Bueno, hecho esto, ahora vamos a hacer conexiones a bases de datos en local, concretamente a la máquina virtual del profesor.

Base de datos: aluBD
Usuario: alumno
Contraseña: alupass

Normalmente se tiene el mismo nombre para el usuario y la base de datos, aunque ahora lo hacemos con dos distintos para ver las diferencias.

¿Y como conectamos?
Primero debemos declarar strings con todos los datos necesarios.


También necesitamos un puntero con estructura 



y también declararemos una consulta, para que el código nos quede más limpio


Ahora deberemos inicializar esta estructura, con mysql_init()
Lo que hace es devolver la misma estructura o, si falla, retornar un error

Usaremos fprintf para imprimir los errores por la salida de error para asegurarnos de que nos mostrará el texto siempre que falle, y return 0 lo usaremos para mostrar un código de error previamente definido. En este caso, el 0 para usar un ejemplo.


Lo siguiente será conectarnos a la base de datos con mysql_real_connect(), teniendo que pasarle distintos parámetros, como

  • La estructura MYSQL
  • Servidor de la base de datos
  • Usuario para acceder
  • Contraseña del usuario
  • Base de datos
  • Puerto (por defecto 0)
  • Socket (por defecto NULL)
  • Flags (por defecto 0)

Si la conexión falla, devolverá un resultado de NULL, con lo cual vamos a crear una condición que nos avise de ello, y además usaremos otra función que nos indicará más información sobre dicho fallo, con la funcion mysql_error()

Posteriormente, realizamos la operacion que deseemos sobre la base de datos


Y para finalizar cerraremos la conexión con la base de datos con mysql_close()


El resultado es este



Bueno, ahora que ya hemos comprobado que funciona, quedará ejecutar la consulta en sí.
Para ejecutar la consulta, tenemos que usar la función mysql_query() o bien mysql_real_query().
La única diferencia es que mysql_query() no puede ser usada para trabajar con datos en binario.

Usaremos la segunda, mysql_uery(), que es menos compleja. Posteriormente veremos la otra
Nos devolverá un entero, 0 indicando que la consulta fue un éxito, o diferente de 0 si hubo un error.


Ahora deberemos mostrar el resultado de nuestra consulta. Tenemos, de nuevo, dos opciones

mysql_store_result(). que almacena el resultado en una estructura que deberemos crear. El problema es que si trabajamos con una base de datos enorme, va a consumir mucha capacidad de memoria

mysql_use_result(). Muestra el resultado por pantalla, sin almacenar tanto espacio en memoria. Por el contrario, es más propenso a caídas porque está más rato conectado.

Usaremos la segunda.

Declaramos la estructura, e inicializamos un registro de consulta que la almacenamos en ese campo (despues de conectar a la base de datos).




Nuestro resultado se irá almacenando en una serie de filas, así que lo recogeremos fila a fila con un while, usando la función de mysql_fetch_row()
Algo así como "coger la fila de mysql, en traducción muy literal".
Primero declaramos la estructura al inicio del código



 Y después, debajo de la función para mostrar el resultado, capturamos y mostramos el primer registro



Ahora vamos a realizar el control de errores de todas las funciones en las que no las habiamos realizado;


Lo que haremos ahora será modificar la función de capturar registro para que lo haga automático con todos los registros y campos. Esto lo haremos a través de un while y for, es decir, primero declaramos lo siguiente


Y modificamos la captura del registro haciéndolo así


También hay que liberar la memoría ANTES de cerrar la conexión



Y aquí podemos visualizar el resultado


Esteticamente feo de cojones, pero funcional.

Aquí dejo el código completo, que si no se hace paso a paso yo al menos me perdería

#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>

int main()
{
    char *servidor="192.168.137.114";
    char *usuario="alumno";
    char *password="alupass";
    char *bd="aluBD";

    MYSQL *conexion=mysql_init(NULL);
    MYSQL_RES *resultado;
    MYSQL_ROW registro;
    unsigned int num_campos;
    int i;

    char *consulta="SELECT * FROM CLIENTES";

    // Inicializamos la estructura
    if (conexion==NULL) {
        fprintf(stderr,"La inicialización de la estructura MYSQL* ha fallado. Posible falta de memoria \n");
        return 0;
    }


    // Conectamos con la base de datos
    if (mysql_real_connect(conexion, servidor, usuario, password, bd, 0, NULL, 0)==NULL) {
        fprintf(stderr,"La conexión con el servidor ha fallado con el siguiente error: %s \n",mysql_error(conexion));
        return 0;

    }


    // Consulta a realizar
    if (mysql_query(conexion, consulta)!=0) {
        fprintf(stderr, "La consulta ha fallado");
        return 0;
    }

    // Almacenar en memoria uno a uno
    if ( ( resultado=mysql_use_result(conexion) )==NULL) {
        fprintf(stderr,"La obtención del resultado ha fallado \n");
        return 0;
    }

    // Capturar el registro a usar
    num_campos=mysql_num_fields(resultado);
    while ((registro=mysql_fetch_row(resultado))!=NULL) {

        //Imprimir el primer y segundo campo de la consulta
         for (i=0;i<num_campos;i++) {
            fprintf(stdout," %s |", registro[i]);
        }
    }

    printf("La versión actual del cliente MySQL es %s", mysql_get_client_info());
    
    // Liberar memoria
    mysql_free_result(resultado);

    mysql_close(conexion);
    return 0;
}

0 comentarios:

Publicar un comentario