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:
Call Ns_PdSendString with an OK_STATUS.
Call Ns_PdSendRowInfo to send to the client the column info.
Call Ns_PdSendRowInfo to send to the client subsequent row info.
Call Ns_PdSendData to indicate to the client that END_DATA has been reached.
If an exception occurs during the processing of the row info, then this function should send the partial data to the client and indicate an error with Ns_PdDbLog. You do not need to send END_DATA first in this case.
If an exception is raised before successfully retrieving some of the row info, then this function should call Ns_PdSendException to return an error.
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".
/* DBMSState and DBMSGetRow are 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);
}
}
|