static RETCODE SQL_API ARDGetField()

in sql-odbc/src/sqlodbc/opensearch_api30.c [873:1036]


static RETCODE SQL_API ARDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
                                   SQLSMALLINT FieldIdentifier, PTR Value,
                                   SQLINTEGER BufferLength,
                                   SQLINTEGER *StringLength) {
    UNUSED(BufferLength);
    RETCODE ret = SQL_SUCCESS;
    SQLLEN ival = 0;
    SQLINTEGER len, rettype = 0;
    PTR ptr = NULL;
    const ARDFields *opts = &(desc->ardf);
    SQLSMALLINT row_idx;

    len = sizeof(SQLINTEGER);
    if (0 == RecNumber) /* bookmark */
    {
        BindInfoClass *bookmark = opts->bookmark;
        switch (FieldIdentifier) {
            case SQL_DESC_DATA_PTR:
                rettype = SQL_IS_POINTER;
                ptr = bookmark ? bookmark->buffer : NULL;
                break;
            case SQL_DESC_INDICATOR_PTR:
                rettype = SQL_IS_POINTER;
                ptr = bookmark ? bookmark->indicator : NULL;
                break;
            case SQL_DESC_OCTET_LENGTH_PTR:
                rettype = SQL_IS_POINTER;
                ptr = bookmark ? bookmark->used : NULL;
                break;
        }
        if (ptr) {
            *((void **)Value) = ptr;
            if (StringLength)
                *StringLength = len;
            return ret;
        }
    }
    switch (FieldIdentifier) {
        case SQL_DESC_ARRAY_SIZE:
        case SQL_DESC_ARRAY_STATUS_PTR:
        case SQL_DESC_BIND_OFFSET_PTR:
        case SQL_DESC_BIND_TYPE:
        case SQL_DESC_COUNT:
            break;
        default:
            if (RecNumber <= 0 || RecNumber > opts->allocated) {
                DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR,
                             "invalid column number");
                return SQL_ERROR;
            }
    }
    row_idx = RecNumber - 1;
    switch (FieldIdentifier) {
        case SQL_DESC_ARRAY_SIZE:
            ival = opts->size_of_rowset;
            break;
        case SQL_DESC_ARRAY_STATUS_PTR:
            rettype = SQL_IS_POINTER;
            ptr = opts->row_operation_ptr;
            break;
        case SQL_DESC_BIND_OFFSET_PTR:
            rettype = SQL_IS_POINTER;
            ptr = opts->row_offset_ptr;
            break;
        case SQL_DESC_BIND_TYPE:
            ival = opts->bind_size;
            break;
        case SQL_DESC_TYPE:
            rettype = SQL_IS_SMALLINT;
            switch (opts->bindings[row_idx].returntype) {
                case SQL_C_TYPE_DATE:
                case SQL_C_TYPE_TIME:
                case SQL_C_TYPE_TIMESTAMP:
                    ival = SQL_DATETIME;
                    break;
                default:
                    ival = opts->bindings[row_idx].returntype;
            }
            break;
        case SQL_DESC_DATETIME_INTERVAL_CODE:
            rettype = SQL_IS_SMALLINT;
            switch (opts->bindings[row_idx].returntype) {
                case SQL_C_TYPE_DATE:
                    ival = SQL_CODE_DATE;
                    break;
                case SQL_C_TYPE_TIME:
                    ival = SQL_CODE_TIME;
                    break;
                case SQL_C_TYPE_TIMESTAMP:
                    ival = SQL_CODE_TIMESTAMP;
                    break;
                default:
                    ival = 0;
                    break;
            }
            break;
        case SQL_DESC_CONCISE_TYPE:
            rettype = SQL_IS_SMALLINT;
            ival = opts->bindings[row_idx].returntype;
            break;
        case SQL_DESC_DATA_PTR:
            rettype = SQL_IS_POINTER;
            ptr = opts->bindings[row_idx].buffer;
            break;
        case SQL_DESC_INDICATOR_PTR:
            rettype = SQL_IS_POINTER;
            ptr = opts->bindings[row_idx].indicator;
            break;
        case SQL_DESC_OCTET_LENGTH_PTR:
            rettype = SQL_IS_POINTER;
            ptr = opts->bindings[row_idx].used;
            break;
        case SQL_DESC_COUNT:
            rettype = SQL_IS_SMALLINT;
            ival = opts->allocated;
            break;
        case SQL_DESC_OCTET_LENGTH:
            ival = opts->bindings[row_idx].buflen;
            break;
        case SQL_DESC_ALLOC_TYPE: /* read-only */
            rettype = SQL_IS_SMALLINT;
            if (DC_get_embedded(desc))
                ival = SQL_DESC_ALLOC_AUTO;
            else
                ival = SQL_DESC_ALLOC_USER;
            break;
        case SQL_DESC_PRECISION:
            rettype = SQL_IS_SMALLINT;
            ival = opts->bindings[row_idx].precision;
            break;
        case SQL_DESC_SCALE:
            rettype = SQL_IS_SMALLINT;
            ival = opts->bindings[row_idx].scale;
            break;
        case SQL_DESC_NUM_PREC_RADIX:
            ival = 10;
            break;
        case SQL_DESC_DATETIME_INTERVAL_PRECISION:
        case SQL_DESC_LENGTH:
        default:
            ret = SQL_ERROR;
            DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
                         "invalid descriptor identifier");
    }
    switch (rettype) {
        case 0:
        case SQL_IS_INTEGER:
            len = sizeof(SQLINTEGER);
            *((SQLINTEGER *)Value) = (SQLINTEGER)ival;
            break;
        case SQL_IS_SMALLINT:
            len = sizeof(SQLSMALLINT);
            *((SQLSMALLINT *)Value) = (SQLSMALLINT)ival;
            break;
        case SQL_IS_POINTER:
            len = sizeof(SQLPOINTER);
            *((void **)Value) = ptr;
            break;
    }

    if (StringLength)
        *StringLength = len;
    return ret;
}