Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Passing MYSQL results in C 1

Status
Not open for further replies.

DMAN3021

Programmer
Aug 20, 2002
40
CA
I posted this in the MYSQL forum, but thought I might want to try the C forum, cause its more of a C question.

I'm working on a C program that uses MYSQL to access and modify a database. Right now, I am trying to run a SELECT query on the database, and to populate a list with the results.

The thing is, in all the examples I can find, the MYSQL_RES structure is processed locally. I on the other hand, want an outside function to call my run_query() function, and then process the result set itself.

The problem I get is that the MYSQL_RES I receive from my query function is not good. Even when I debug, I can see that I have a correct result set, up until I exit my query function and return to my list function.

Anyone have an example of how to correctly pass a MYSQL_RES structure from one function to another?

Heres my code:

in connect.c
Code:
/* Run a query */
int run_query(char *query, MYSQL_RES *res_set) {
  
    if (open_connection() != 1) {
        /* could not connect to MySQL */
        print_error(&connection, "Unable to connect to MySQL");
        return 0;
        
    } else {
        if (mysql_query(&connection, query) != 0) {
            /* Query has failed */
            print_error(&connection, "Query FAILED!\n");
            close_connection();
            return 0;
            
        } else {
            /* Query has passed, process results */
            res_set = mysql_store_result(&connection);
            
            if (res_set) {
                /* If a result set was returned */
                process_result_set(res_set);
                mysql_free_result(res_set);
            } else {
                /* No result was returned */
                if (mysql_field_count(&connection) == 0) {
                    printf("%lu rows affected\n", (unsigned long) mysql_affected_rows(&connection));                
                } else { /* an error occured */
                    print_error(&connection, "Could not retrieve the result set");
                }
            }
        }
        
        close_connection();
    }    
    return 1;
}

in list.c
Code:
int
List( )

    {
    MYSQL_RES *res_set;
    MYSQL_ROW    row;
    MYSQL_FIELD    *field;
    char *query = "SELECT * FROM THETABLE";
    int i;

    /* Get the list */
    run_query_result(query, res_set);
    
    /*Lets try some stuff with res_set */
    mysql_field_seek(&res_set, 0);
    for (i=0; i<mysql_num_fields(&res_set); i++) {
        field = mysql_fetch_field(&res_set);
        if (row[i] == NULL) {
            printf("NULL\t");
        } else {
            printf("%s\t", row[i]);
        }
    }
    
    return( Pt_CONTINUE );
}
 
What's a true problem with a passing of a pointer to a structure in another routine? If you have a pointer to allocated (by mysql_store_result) structure, you may pass it anywhere, pass to another functions (to fetch rows) etc. Don't forget to free the result structure (by mysql_free_result) - that's all. I don't understand, what's a desired example of a basic C activity (pass a pointer via parameter) you need.

Another story that it seems the snippet above demonstrates a slightly unusual processing of MySQL contacts. For example, you open connection for every query (by global function w/o parameters) then use global variables and we (and you;) can't see where these variables was initialized - and so on.

Obviously you have a problem in List() function. You pass a pointer to MYSQL_RES but you can't get a new its value from run_query_result! Remember: C passes all parameters by value. In called function you assign a value to copy of passed value/ This new value never returns in argument.

If you want to get MYSQL_RES pointer from a function, you must pass a pointer to pointer argument (MYSQL_RES**), for example:
Code:
int f(.... MYSQL_RES** pres)
{
   MYSQL_RES* res;
   ...
   res = mysql_store_result(...);
   ...
   *pres = res;
   ...
}
....
  MYSQL_RES* res;
  ...
  f(...,&res);
  ...
Indeed, it was not MySQL issue. Think about C language calling conventions in general...
 
Excellent, that fixed it right up!

And your other points are well taken. I did, however, do on purpose not to post all of my connect.c code here, because the message would have been just be to big (I have a couple of different query functions depending on the result I want back).

So I can assure you that all globals variables are set correctly, and this finnaly works like a charm! Thanks!
 
Very pleased to help you.
Try to keep MySQL connection in opened state as long as possible, don't close it after every query.
Good luck!
 
Is there a reason why would I want to do that?
 
Because opening an closing connections to the db is a very time consuming job.

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top