Quote Retrieval

The get_stock( ) function provides all stock information from MySQL for the stock with the specified symbol. It formulates a query based on the ticker symbol and sticks the results into a Stock structure.

Stock *get_stock(char *symbol) {
    char *query = "SELECT symbol, openPrice, currPrice, high52, low52, 
                  FROM Stock WHERE symbol = '%s'";
    char *sql;
    int state;
  
    error = (char *)NULL;
    sql = (char *)malloc((strlen(query) + strlen(symbol) + 1) * sizeof(char));
    sprintf(sql, query, symbol);
    state = mysql_query(connection, sql);
    free(sql);
    if( state != 0 ) {
        error = mysql_error(connection);
        return (Stock *)NULL;
    }
    else {
        MYSQL_RES *result;
        Stock *stock;
        MYSQL_ROW row;
  
        result = mysql_store_result(connection);
        if( result == (MYSQL_RES *)NULL ) {
            error = mysql_error(connection);
            return (Stock *)NULL;
        }
        stock = (Stock *)malloc(sizeof(Stock));
        row = mysql_fetch_row(result);
        if( !row ) {
            error = "Invalid symbol.";
            return (Stock *)NULL;
        }
        stock->symbol = row[0];
        stock->open_price = atof(row[1]);
        stock->current_price = atof(row[2]);
        stock->high52 = atof(row[3]);
        stock->low52 = atof(row[4]);
        return stock;
    }
}

The first line of the function is where we prepare the query. It includes the entire query except for a %s placeholder for the ticker symbol. We will insert this into the string later using sprintf( ) .

The function next clears out the error message used by the get_error( ) helper function. Clearing out the error message is critical since MySQL actually manages the memory allocated to MySQL error messages. If this function failed to clear out the error message, and the client calling this API tried to call get_error( ) when no error occurred, it would be possible for the error message to point to garbage memory.

To make sure the final SQL has enough memory allocated to it, the function allocates enough space for the query with the placeholder, the ticker symbol, and a final null terminator. Using sprintf( ), the query is assembled into its final SQL.

In applications in which the stock symbol may come from data entered by a user, either your application or—perhaps more appropriately—the API should check the ticker symbol for validity. In other words, you should scan it for SQL, especially single quotes. If you fail to check for these things, users may inadvertently cause errors in the database calls or—even worse—exploit the error to corrupt the database.

Immediately after running the query, the API frees the memory allocated for the query and proceeds to error handling. As we illustrated earlier, you check the error on a query by checking its return value. If the return value is nonzero, an error occurred. This API sets the value of the current error message to whatever mysql_error( ) has set and returns NULL to the calling application.

On success, the function retrieves the results of the query. For this query, it is looking for one and only one result. The call to mysql_store_result( ) gets the result set from MySQL. The mysql_store_result( ) function returns NULL under two conditions:

  • The original SQL was not a query (i.e., it was an INSERT, UPDATE, or DELETE).

  • The function encountered an error.

Because we know we sent a query to the database, this situation can mean only that an error has occurred. We therefore set the error message and return null.

We are now ready to allocate a Stock struct and assign it values. This example actually does row processing in a different manner from what we did earlier. It specifically calls mysql_fetch_row( ) instead of directly accessing the data through the MYSQL_RES struct. Though both methods are proper, mysql_fetch_row( ) is technically more proper. It enables you to step through a result set row by row and get meta-data for the row. Though we care about neither issue in this case, we still use that function.

The mysql_fetch_row( ) function will return a MYSQL_ROW struct if there are more rows in the result set. For this query, there should be only one row. If the call to mysql_fetch_row( ) returns NULL, the symbol simply is not in the database. We therefore check that it is in the database and begin assigning values to the Stock struct based on the data in the result set.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset