|   | ![[ Previous ]](navbprev.gif)  ![[ Contents ]](navbhome.gif)  ![[ Index ]](navbhelp.gif)  ![[ Next ]](navbnext.gif)  | 
Send system catalog information about a table to the client.
void Ns_PdDbGetTableInfo(void *handle, char *tableName);
This function should retrieve the system catalog information (columns, types, etc.) about a table and send this to the client.
Returning a successful status of DB_ROWS indicates that the SQL query was the type of query that returned rows (e.g., SELECT), rather than a manipulation statement that does not return rows. If the initial SQL select query returns a successful status of DB_ROWS, then this function should:
Ns_PdDbGetTableInfo() describes the table by sending back three columns of data, named "ColName," "ColType," and "NotNull" respectively. These column names are sent to the server with an Ns_PdSendRowInfo() call. Then, each column of the table is described by sending a 3-column row to the server, giving the name, type and nullability of the table's column. Again, Ns_PdSendRowInfo() is used to send this information to the AOL Server. The type is specified as a string (one of the types from Ns_PdDbGetTypes()). The nullability is specified as either the string "t" or "f".
    /* Things italicized would be your DBMS-specific structures and 
calls. */
    /* defined in nspd.h */ 
    typedef struct Ns_PdRowData {
    int elSize;
    char *elData;
    } Ns_PdRowData;
    typedef struct Ns_PdRowInfo {
        int             numColumns;
        Ns_PdRowData   *rowData;
    }; 
    void 
    Ns_PdDbGetTableInfo(void *handle, char *tableName) { 
        DBMSState    *state = (DBMSState *) handle;    
        Ns_PdRowInfo        *getRowInfo, *bindRowInfo;
        int                  status = NS_ERROR;
        int                  getRowRet;
        /* Exec SQL and "select" data from a table */
        Ns_PdLog(Trace, "gettableinfo(%s):", tableName);
        sprintf(state->sqlbuf,
            "select c.column_name, c.column_type, c.column_notnull"
            " from columns c, tables t"
            " where t.table_name = '%s'"
            " and c.column_member = t.table_type;", tableName);
        status = DBMDExec(state, state->sqlbuf);
        if (status == DB_ROWS) {
           if ((bindRowInfo = DBMSBindRow(state)) != NULL) {
           
              getRowInfo = 
Ns_PdNewRowInfo(Ns_PdGetRowInfoNumColumns(bindRowInfo));
              if (getRowInfo != NULL) {
                   status = NS_OK;
                   Ns_PdSendString(OK_STATUS);
                   Ns_PdSendRowInfo(bindRowInfo);  /* sends list of 
column names */
                   while ((getRowRet = DBMSGetRow(handle, 
                           getRowInfo)) == NS_OK) {
                           /* send row info */
                           Ns_PdSendRowInfo(getRowInfo);
                   }
                   Ns_PdSendData(END_DATA, strlen(END_DATA)); /* NULL 
row terminates rows */
                   if (getRowRet == DB_END_DATA) {
                       status = NS_OK;
                   } else {
                       Ns_PdLog(Error, "GetTableInfo: incomplete data 
sent to client (table=%s)",
                                tableName);   
                   }        
                   /* free the getRowInfo structure when done */
                   Ns_PdFreeRowInfo(getRowInfo, 0);
               
              }
              /* free the bindRowInfo data and structure when done */
              Ns_PdFreeRowInfo(bindRowInfo, 1);
           }
       }
       if (status != NS_OK) {
            Ns_PdSendException(state->exceptionCode, 
    state->exceptionMsg);
       }
    }