Ns_PdDbBestRowId

Name

Ns_PdDbBestRowId -- Send primary key to the client.

Syntax

void Ns_PdDbBestRowId (void *handle, char *tableName);

Description

This function retrieves the primary key of a table from the database and sends this to the client. If a table has a primary key, AOLserver can perform row updates and deletes. If the best-row-id operation is successful, this function should call Ns_PdSendString with an OK_STATUS. If a best-row-id is found then call Ns_PdSendString with the column name; otherwise, call Ns_PdSendString with NO_BESTROWID. On failure this function should return an exception code with Ns_PdSendException.

Pseudo-code Example

/* Things italicized would be your DBMS-specific structures and calls. */
#define MAX_COLUMN_NAME 1024

/* This would be a SQL statement to get the primary key */
#define SQL_FINDKEY /* ... */

void
Ns_PdDbBestRowId(void *handle, char *tableName) {
  DBMSState *state = (DBMSState *)handle;
  Ns_PdRowInfo *bindRowInfo, *getRowInfo;
  static char tableColName[] = "name";
  char columnName[MAX_COLUMN_NAME];
  int i;
  int done = 0;
  int status = NS_ERROR;
  int getRowRet;
  Ns_PdLog(Trace, "bestrowid(%s):", tableName);
  columnName[0] = '\0';

  /* query for a primary key first */
  sprintf(state->sqlbuf, SQL_FINDKEY, tableName, "key1", tableName);
  for (i = 0; !done && (i DBMSExec(state, state->sqlbuf)) == DB_ROWS) {
    if ((bindRowInfo = DBMSBindRow(state)) != NULL) {
      char *itemVal;
      int itemSize;
      int nameIndex;
      if ((getRowInfo = Ns_PdNewRowInfo(Ns_PdGetRowInfoNumColumns(bindRowInfo))) != NULL) {
        status = NS_OK;
        if ((getRowRet = DBMSGetRow(state, getRowInfo)) == NS_OK) {
          if ((nameIndex = Ns_PdFindRowInfoValue(bindRowInfo, tableColName, strlen(tableColName))) == -1 ) {
            Ns_PdLog(Error, "DbBestRowId:  NULL \"%s\" column in %s table, %s key.", tableColName, tableName, i==0 ? "primary" : "secondary");
          } else {
            Ns_PdGetRowInfoItem(getRowInfo, nameIndex, &itemVal, &itemSize);
            strcpy(columnName, itemVal);
          } 
        } else {
          if (i == 0) { /* if first try */
            if (getRowRet != DB_END_DATA) {
              DBMSCancel(state);
            }
            /* no primary key was found so look for a secondary key */
            sprintf(state->sqlbuf, SQL_FINDKEY, tableName, "key2", tableName);
            done = 0;
          } else { /* secondary key failed */
            Ns_PdLog(Trace, "DbBestRowId: Primary and secondary key search failed.");
            strcpy(columnName, NO_BESTROWID);
          }
        }
        Ns_PdFreeRowInfo(getRowInfo, 0);
      }
      Ns_PdFreeRowInfo(bindRowInfo, 1);
    }
  }

  DBMSCancel(state);
  if (status == NS_ERROR) {
    Ns_PdSendException(state->exceptionCode, state->exceptionMsg);
  }  else {
    Ns_PdSendString(OK_STATUS);
    Ns_PdSendString(columnName);
  }
}