Receiving Results from a Remote Database

This example uses the handle_results callback function, which processes results from the remote database and sends them to the client.

  1. Define the function and the function parameters for handle_results:
    int handle_results (rmtproc, srvproc)
    DBPROCESS   FAR * rmtproc;    // DBPROCESS handle          
                                  // to the remote database    
    SRV_PROC    FAR * srvproc;    // Process handle to send    
                                  // results to the client     
    
    {
        short    cols;            // Data columns returned     
        int      i;               // Index variable            
        DBINT    rows;            // Number of rows sent       
        BOOL     results_sent;    // Number of results sets sent  
        BOOL     gotcompute;      // COMPUTE row indicator     
        short *  paramarray;      // Return parameters         
        RETCODE  returnvalue;     // Value returned from       
                                  // DB-Library calls          
    
  2. Use the DB-Library dbresults callback function to loop through each results set. Since a command can consist of multiple commands or a single command that has multiple results sets, use a WHILE loop to process each results set:
    // Process the results from the remote database.   
    
    while (TRUE)
    {
           returnvalue = dbresults (rmtproc);
           if (returnvalue == NO_MORE_RESULTS)
               break;
    }
    
  3. Get the number of data columns in the row using the DB-Library dbnumcols function, and describe each column in the row using the srv_describe function:
    cols = dbnumcols (rmtproc); // How many data columns             
                                // are in the row?                   
    for (i = 1; i <= cols; i+) // Call srv_describe for each column 
    
    {
         srv_describe (srvproc,
                       i,
                       dbcolname (rmtproc, i),
                       SRV_NULLTERM,
                       (DBINT)dbcolntype (rmtproc, i),
                       dbcollen (rmtproc, i),
                       (DBINT)dbcolntype (rmtproc, i),
                       dbcollen (rmtproc, i),
                       (BYTE *)NULL);
    }
    

    You may also need to use srv_setutype to set the user-defined datatype information for a column. For more information, see the GATEWAY sample application.

  4. Set the address of the column data using srv_setcoldata and the length of the column data using srv_setcollen. Move the row from the remote database to the client using the srv_sendrow function:
    rows = 0;  // Initialize a counter for the row number.
    while (TRUE)
    
    {
           returnvalue = dbnextrow (rmtproc);
           if (returnvalue == NO_MORE_ROWS)   // No more rows so exit  
                                              // loop, set the DONE    
                                              // status, and exit.     
                break;
    
           // Move the row from the remote database to the client.     
    
           for (i = 1; i <= cols; i+)
    
           { 
                srv_setcollen (srvproc, i,
                     (short)dbdatlen (rmtproc, i));
                srv_setcoldata (srvproc, i, dbdata(rmtproc, i));
            }
    
            // Send the row to the client.     
    
           if (srv_sendrow (srvproc) == SUCCEED)
               rows+;                        // Go to the next row. 
    }
    
  5. Determine if the count value in the remote database is relevant and, if so, pass it to the client. Send a completion message for the current results set:
    if (dbnumcols (rmtproc) > 0)
        rows = DBCOUNT(rmtproc)  0L ? 0L: rows;
    else
    {
        rows = DBCOUNT (rmtproc);
    
       // Now set the flag so a completion message is sent for the  
       // current results set.                                      
       results_sent = TRUE;
    
    }
    
    // Send the final done packet for the execution of the command  
    // batch. The previous batch was one that might have returned   
    // rows, so set the DONE status accordingly.                    
    if (rows > 0)
        srv_senddone (srvproc,
                  SRV_DONE_COUNT | SRV_DONE_FINAL,
                  (DBUSMALLINT) 0,
                  rows);
    else 
        srv_senddone (srvproc,
                  SRV_DONE_FINAL,
                  (DBUSMALLINT) 0,
                  (DBINT) 0);
    
  6. Once a set of results has been retrieved from the remote database, a completion message must be sent to the client for the last results set retrieved. This must be done before another set of results can be obtained.
    // If this is the second time through the loop, send a completion 
    // message to the client for the previous results set sent.       
        if (results_sent == TRUE)
          {  // If the previous batch returned rows, set              
             // the DONE status accordingly.                          
             if (rows > 0)
                  srv_senddone (srvproc,
                            SRV_DONE_MORE | SRV_DONE_COUNT,
                            (DBUSMALLINT)0,
                            rows);
             else
                  srv_senddone (srvproc,
                            SRV_DONE_MORE,
                            (DBUSMALLINT)0,
                            (DBINT) 0);
             }