Estructuras dinámicas a partir de consultas de BD

Moderadores: Kravenbcn, largeroliker, fidelcastro, cerealkiller, pspCaracas, m0skit0, LnD, ka69, zacky06

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

Tengo definidas varias estructuras que pueblo a partir de consultas de base de datos. Algo como:

Código: Seleccionar todo

int size;

main{

   size = getNumRows("persona")

   struct persona[size]

  getPeople(persona)

}

int getNumRows(char *tabla){

  int numOfRows;
  char sql = "select * from ";
  strcat(sql, tabla);

  executeQuery(sql);

   numOfRows  = fetchNumOfRows();

   return numOfRows;
}


void getPeople(struct persona[ ]){

  int i;
  char sql = "select * from peole";

   executeQuery(sql);

   numOfRows  = fetchNumOfRows();

   for(i=0;fetchRow != NULL,i++){

      persona[i].nombre = fetchField(0);
      persona[i].nombre = fetchField(1);

      ...

   }
   
}


Como pueden ver en el main, requiero ejecutar dos consultas a la base de datos, una primera consulta para saber el tamaño de la estructura "dinámica", y luego una segunda vez para llenar los datos.

Ahora mi pregunta: ¿Hay alguna forma de hacer esto en una sola función? He pensado en hacer la declaración de la estructura en la segunda función a través de un puntero...y de esta forma me arroaría una consulta a la base de datos.

¿Alguna idea de cómo hacerlo? O algún sitio donde leer?
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por m0skit0 »

Siento la tardanza... ¿Conseguiste resolver esto?
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

De momento no...he tenido que sobrevivir con las dobles consultas :(

Mi duda en esencia es si se pueden declarar estructuras dinámicas y cambiarles el tamaño a voluntad (en ejemplo dependiendo de la cantidad de registros que arroje la base de datos consultada).

No te preocupes por la tardanza...como todo, se responde cuando se puede!! (regla n° 1 de listas de correos y foros)
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por m0skit0 »

Primero, una bronca: ¡usa las etiquetas [code] para el código!

Segundo, otra brona: ¡no uses variables globales!

A ver si he entendido bien tu problema: lo que quieres es que el array persona sea dinámico, es decir, que pueda variar dependiendo de cuántas entradas tenga la tabla. Además quieres hacerlo en una sola consulta.
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

m0skit0 escribió:Primero, una bronca: ¡usa las etiquetas [code] para el código!

Listo!
m0skit0 escribió:Segundo, otra brona: ¡no uses variables globales!

Entendido!!
m0skit0 escribió:A ver si he entendido bien tu problema: lo que quieres es que el array persona sea dinámico, es decir, que pueda variar dependiendo de cuántas entradas tenga la tabla. Además quieres hacerlo en una sola consulta.

Exacto!!
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por m0skit0 »

Aclarar que yo no he hecho consultas a BBDD en C...

Supongo que executeQuery() te tiene que devolver un result set o algo parecido. En vez de devolver el número de filas, devuelve el result set entero, así podrás consultar tanto los datos como el número de filas cuando desees.

En cuanto a la estructura dinámica, es bastante fácil (asumiendo que el struct se llama persona - te aconsejo que uses typedef struct en vez de struct a secas):

Código: Seleccionar todo

persona* personas;
unsigned long long size = getSize();
personas = (persona*) malloc(size * sizeof(persona));
personas[0]; etc...
free(personas);
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

Voy a proba a ver cómo me va...

¿Y cuál es la diferencia con typdef?
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
m0skit0
Administrador
Administrador
Mensajes: 5585
Registrado: 03 Sep 2009, 09:35
Ubicación: 0xdeadbeef

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por m0skit0 »

pspCaracas escribió:¿Y cuál es la diferencia con typdef?

No necesitas andar poniendo struct delante todo el rato :mrgreen:

Ah y con

m0skit0 escribió:devuelve el result set entero

me refiero a un puntero :D
Imagen

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

m0skit0 escribió:
pspCaracas escribió:¿Y cuál es la diferencia con typdef?

No necesitas andar poniendo struct delante todo el rato :mrgreen:


Esto mola muchísimo!!!

m0skit0 escribió:Ah y con

m0skit0 escribió:devuelve el result set entero

me refiero a un puntero :D


Eso si lo había entendido/asumido!!
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Avatar de Usuario
pspCaracas
Moderador Global
Moderador Global
Mensajes: 3080
Registrado: 03 Sep 2009, 03:29
Ubicación: Buenos Aire - Argentina
Contactar:

Re: Estructuras dinámicas a partir de consultas de BD

Mensaje por pspCaracas »

Ya lo logré, pero faltaron apuntadores ¬¬

Busqué un poco más para completar tu ejemplo m0skit0, y encontré este de cómo reservar arreglos multidimensionales (en inglés para el que lo quiera revisar).

En mi caso tengo esto:

En el SQL.h

Código: Seleccionar todo


struct definition {
   int id;
   char valueType[10];
   float value;            
   int time;            
};

int getDefinition(MYSQL *, struct histDefinition **);


En el SQL.c

Código: Seleccionar todo

int getDefinition(MYSQL *conn, struct definition  **def){

   MYSQL_STMT *stmt;
   char *sql;

   // Bind variables
   MYSQL_BIND result[4];

   int myId, myTime;
   float myValue;
   char myValueType[10];
   unsigned long myValueTypeLength;

   my_bool is_null[3];
   my_ulonglong  numRows;

   int i;

   sql = "select * DefinitionTable";

   // Statement handler
   statementHandler(&conn, &stmt, &sql);

   // Initialize the result column structures
   memset(result, 0, sizeof(result)); /* zero the structures */

   // Init param structure
   // Result
   result[0].buffer_type    = MYSQL_TYPE_LONG;
   result[0].buffer       = (void *) &myId;
   result[0].is_unsigned   = 0;
   result[0].is_null       = &is_null[0];
   result[0].length       = 0;

   result[1].buffer_type    = MYSQL_TYPE_FLOAT;
   result[1].buffer       = (void *) &myValue;
   result[1].is_unsigned   = 0;
   result[1].is_null       = &is_null[1];
   result[1].length       = 0;

   result[2].buffer_type    = MYSQL_TYPE_LONG;
   result[2].buffer       = (void *) &myTime;
   result[2].is_unsigned   = 0;
   result[2].is_null       = &is_null[2];
   result[2].length       = 0;

   result[3].buffer_type    = MYSQL_TYPE_STRING;
   result[3].buffer       = (void *) myValueType;
   result[3].buffer_length   = sizeof (myValueType);
   result[3].is_null       = &is_null[4];
   result[3].length       = &myValueTypeLength;


   // Bind result
   if (mysql_stmt_bind_result(stmt, result) != 0) {
      print_stmt_error(stmt, "Could not bind results");
      return -1;
   }

   // Execute!!
   if (mysql_stmt_execute(stmt) != 0) {
      print_stmt_error(stmt, "Could not execute statement");
      return -1;
   }

   if (mysql_stmt_store_result(stmt) != 0) {
      print_stmt_error(stmt, "Could not buffer result set");
      return -1;
   }

   // Get the number of rows
   numRows = mysql_stmt_num_rows (stmt);

       // Dynamic structure
   *def = (struct definition*) malloc (numRows * sizeof(struct definition));

   // Fetch
   for(i=0; mysql_stmt_fetch (stmt) == 0; i++){

      // Init data
      (*def)[i].id       = 0;
      (*def)[i].value   = 0;
      (*def)[i].time   = 0;
      strcpy((*def)[i].valueType,"");

      (*def)[i].id       = myId;
      (*def)[i].deadband   = myValue;
      (*def)[i].deadtime   = myTime;
      strncpy((*def)[i].valueType, myValueType, strlen(myValueType));
      (*def)[i].valueType[strlen(myValueType)] = '\0';

   }

   // Deallocate result set
   mysql_stmt_free_result(stmt);

   // Close the statement
   mysql_stmt_close(stmt);

   return ((int) numRows);

}




En el programa.c

Código: Seleccionar todo

int main(){

    int numHistDef;

    // Open database
    openDB(&conn);

    struct definition *def = NULL;

    numDef = getDefinition(conn, &def);

    syslog(LOG_INFO,"> num of Definitions: %d", numHistDef);

    for (i = 0; i < numDef; i++) {

      syslog(LOG_INFO, "> def[%d].id: %d", i, def[i].id);
      syslog(LOG_INFO, "> def[%d].value: %f", i, def[i].value);
      syslog(LOG_INFO, "> def[%d].time: %d", i, def[i].time);
      syslog(LOG_INFO, "> def[%d].valueType: %s",i, def[i].valueType);
    }
   exit(0);
}



Salida:

Código: Seleccionar todo

Aug 19 15:14:53 buckbeak programa: > num of Definitions: 3
Aug 19 15:14:53 buckbeak programa: > def[0].id: 1
Aug 19 15:14:53 buckbeak programa: > def[0].value: 0.100000
Aug 19 15:14:53 buckbeak programa: > def[0].time: 30
Aug 19 15:14:53 buckbeak programa: > def[0].valueType: fsw
Aug 19 15:14:53 buckbeak programa: > def[1].id: 3
Aug 19 15:14:53 buckbeak programa: > def[1].value: 10.000000
Aug 19 15:14:53 buckbeak programa: > def[1].time: 30
Aug 19 15:14:53 buckbeak programa: > def[1].valueType: fsw
Aug 19 15:14:53 buckbeak programa: > def[2].id: 5
Aug 19 15:14:53 buckbeak programa: > def[2].value: 5.000000
Aug 19 15:14:53 buckbeak programa: > def[2].time: 20
Aug 19 15:14:53 buckbeak programa: > def[2].valueType: fsw




Lo bonito del conector de MySQL es que en el mismo result set viene el número de registros, haciendo solo una consulta. Justo lo que quería :)

PD: Te debo los typdef porque aun no soy diestro con eso :P
http://farm3.static.flickr.com/2497/3983880148_f5ae0aaab2_o.png

Responder