3.1.5.2.6 Receiving a CPMGetRowsIn Request

When the server receives a CPMGetRowsIn message request from a client, the server MUST do the following:

  1. Search the ConnectedClientsIdentifiers list for the HANDLE of the named pipe over which the server has received the CPMGetRowsIn message. If it is not present, the server MUST report a STATUS_INVALID_PARAMETER (0xC000000D) error.

  2.  Call the ClientQueryHasCursorHandle abstract interface to the GSS with the HANDLE of the named pipe over which the server has received the CPMGetRowsIn message as its QueryIdentifier argument and with the _hCursor handle as its CursorHandle argument.<29> If _hCursor is invalid, then E_INVALIDARG SHOULD<30> be returned.

  3. Call the HasBindings abstract interface with the HANDLE of the named pipe over which the server has received the CPMGetRowsIn message as its QueryIdentifier argument and with the _hCursor handle as its CursorHandle argument. If the hasBindings output parameter is not true, the server MUST report an E_UNEXPECTED (0x8000FFFF) error.<31>

  4. Prepare a CPMGetRowsOut message by setting the position from which to retrieve the next rows, according to the received SeekDescription:

    • If eType == 0x00000000, then set status = STATUS_INVALID_PARAMETER(0xC000000D).

    • Define oldIndex as the result of calling the GetNextGetRowsPosition abstract interface with QueryIdentifier and CursorHandle as arguments. Then, as a function of eType, call the SetNextGetRowsPosition abstract interface with QueryIdentifier, chapter, and CursorHandle as arguments and with Index set to:

      • If eType == eRowSeekNext (section 2.2.3.11), then Index = oldIndex + _cskip (section 2.2.1.36).

      • If eType == eRowSeekAt (section 2.2.3.11), then Index = GetBookmarkPosition(QueryIdentifier, CursorHandle, _bmkOffset) + _cskip (sections 3.1.7and 2.2.1.36).

      • If eType == eRowSeekatRatio (section 2.2.3.11), then Index = (ulNumerator/ulDenominator) * rcRowsTotal. The value of rcRowsTotal (section 3.1.7) is equal to the output argument of the GetExpensiveProperties abstract interface called with QueryIdentifier and CursorHandle as arguments.

        • When the value of ulDenominator is zero, or if _ulDenominator > _ulNumerator, DB_E_BADRATIO is returned as the error value.

    • If eType == eRowSeekByBookmark (section 2.2.3.11), then for each bookmark handle value in the aBookmarks array (section 2.2.1.38) of the SeekDescription (section 2.2.3.11) argument:

      • Call the GetBookmarkPosition abstract interface to the GSS with QueryIdentifier, CursorHandle, and the bookmark handle value as arguments.

      • Use the bmkIndex (section 3.1.7) returned as an argument to SetNextGetRowsPosition (section 3.1.7), along with QueryIdentifier, CursorHandle, and _chapt.

      • Call the GetRows abstract interface with QueryIdentifier, CursorHandle, 1, and _fBwdFetch as arguments.

  5. After the position is set, retrieve the desired row from the GSS by calling the GetRows abstract interface with the HANDLE of the named pipe over which the server has received the CPMGetRowsIn message as its QueryIdentifier argument, with the _hCursor handle as its CursorHandle argument, with _chapt as its chapter argument, with _cRowsToTransfer as its NumRowsRequested argument, and with _fBwdFetch as its  FetchForward argument. Do this in all cases, except for step 4 bullet 3.

  6. Copy as many rows as fit in a buffer, the size of which is indicated by _cbReadBuffer (section 2.2.3.11), but not more than indicated by _cRowsToTransfer (section 2.2.3.11). Thereafter, reposition the cursor to reflect the actual number of returned rows by calling the SetNextGetRowsPosition abstract interface with QueryIdentifier, CursorHandle and _chapt as arguments and with Index set to the old index (as obtained by calling GetNextRowsPosition(QueryIdentifier, _hCursor, _chapt)) plus the number of rows that fit in the buffer.

  7. If there are no more rows available on the server to finish this request, as signaled by the NoMoreRowsToReturn output parameter for the call made to the GetRows abstract interface (section 3.1.7), the Status fleld of CPMGetRowsOut message MUST be set to DB_S_ENDOFROWSET.

  8. Store the number of rows fetched in _cRowsReturned (section 2.2.3.12), as determined by the NumRowsReturned output parameter from the GetRows call (or, in the case of step 4 bullet 3, the sum of the NumRowsReturned parameters from the GetRows calls).

  9. Copy the _chapt field from the CPMGetRowsIn message to a CPMGetRowsOut message to be sent.

  10. If either of the following cases are true, copy the SeekDescription (section 2.2.3.11) from the CPMGetRowsIn to the CPMGetRowsOut message.

    • The server fails to completely fill the buffer due to a memory allocation failure, but has been able to store at least one row.

      Copying the SeekDescription (section 2.2.3.11) allows the client to continue from the point where the server left off. In addition, the server SHOULD set the error code DB_S_BLOCKLIMITEDROWS, and in the case of CRowSeekAtRatio, convert CRowSeekAtRatio to CRowSeekAt.

    • CRowSeekByBookmark is specified.

    Otherwise, clear SeekDescription (section 2.2.3.11) by setting it to zero.

  11. Store the fetched rows in the Rows field (see section 2.2.3.12 for details on the structure of the Rows field).

    Note Regarding status byte field: If StatusUsed is set to 0x01 in the CTableColumn of the CPMSetBindingsIn message for the column, the server MUST set the status byte (which is located at StatusOffset from the start of the rows) for this column to one of the following values.

     Value

     Meaning

    0x00

    StoreStatusOK

    0x01

    StoreStatusDeferred

    0x02

    StoreStatusNull

  12. Respond to the client with the CPMGetRowsOut message.

    If the property value is absent for this row, the server MUST set the status byte to StoreStatusNull. If the value is too big to be transferred in the CPMGetRowsOut message (greater than 2048 bytes), the server MUST set the status byte to StoreStatusDeferred. Otherwise, the server MUST set the status byte to StoreStatusOK.

  13. Report any errors encountered during message preparation or during any abstract interface call to the GSS. Errors that are specific to this request:

    • E_OUTOFMEMORY: generated by any resource allocation failure on the server or service side.

    • STATUS_INVALID_PARAMETER: generated when any of the parameters passed in by the client is invalid. Invalid parameters are those that do not obey the corresponding data structure layout as defined for their types in this document.

    • STATUS_NO_MEMORY: generated on memory allocation errors.

    • CI_E_NOT_FOUND: generated when the requested property was not found.

    • E_ACCESSDENIED: generated when the client does not have permissions to access a needed resource such as a file result or a catalog.

    • CI_E_BUFFERTOOSMALL: generated when the buffer passed in is too small to accommodate the requested property or properties. This error signals the client to request the potentially large property value separately using a CPMFetchValueIn request.

    Any other error code can be returned, but it will be treated as informative only.