This function should retrieve the list of table names from the database associated with the handle and send this data to the client. The includeSystem parameter indicates whether to include system tables with this list. The function should implement the following protocol:
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 query returns a successful status of DB_ROWS when generating the table names, then this function should:
Call Ns_PdSendString with an OK_STATUS.
Call Ns_PdSendString with a size of the item (table name).
Call Ns_PdSendData to send the actual data associated with the name and to signal the end of data.
If an exception occurs during the processing of the table data, then this function should send the partial data to the client and indicate an error with Ns_PdDbLog.
If an exception is raised before successfully retrieving some of the table data, then this function should call Ns_PdSendException to return an error.
/* 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_PdDbTableList(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);
}
}
|