static RETCODE set_statement_option()

in sql-odbc/src/sqlodbc/options.c [12:260]


static RETCODE set_statement_option(ConnectionClass *conn, StatementClass *stmt,
                                    SQLUSMALLINT fOption, SQLULEN vParam) {
    CSTR func = "set_statement_option";
    char changed = FALSE;
    ConnInfo *ci = NULL;
    SQLULEN setval;

    if (conn)
        ci = &(conn->connInfo);
    else
        ci = &(SC_get_conn(stmt)->connInfo);
    switch (fOption) {
        case SQL_ASYNC_ENABLE: /* ignored */
            break;

        case SQL_BIND_TYPE:
            /* now support multi-column and multi-row binding */
            if (conn)
                conn->ardOptions.bind_size = (SQLUINTEGER)vParam;
            if (stmt)
                SC_get_ARDF(stmt)->bind_size = (SQLUINTEGER)vParam;
            break;

        case SQL_CONCURRENCY:
            /*
             * positioned update isn't supported so cursor concurrency is
             * read-only
             */
            MYLOG(OPENSEARCH_DEBUG, "SQL_CONCURRENCY = " FORMAT_LEN " ", vParam);
            setval = SQL_CONCUR_READ_ONLY;
            if (conn)
                conn->stmtOptions.scroll_concurrency = (SQLUINTEGER)setval;
            else if (stmt) {
                if (SC_get_Result(stmt)) {
                    SC_set_error(
                        stmt, STMT_INVALID_CURSOR_STATE_ERROR,
                        "The attr can't be changed because the cursor is open.",
                        func);
                    return SQL_ERROR;
                }
                stmt->options.scroll_concurrency =
                    stmt->options_orig.scroll_concurrency = (SQLUINTEGER)setval;
            }
            if (setval != vParam)
                changed = TRUE;
            MYPRINTF(0, "-> " FORMAT_LEN "\n", setval);
            break;

        case SQL_CURSOR_TYPE:
            /*
             * if declare/fetch, then type can only be forward. otherwise,
             * it can only be forward or static.
             */
            MYLOG(OPENSEARCH_DEBUG, "SQL_CURSOR_TYPE = " FORMAT_LEN " ", vParam);
            setval = SQL_CURSOR_FORWARD_ONLY;
            if (SQL_CURSOR_STATIC == vParam)
                setval = vParam;
            else if (SQL_CURSOR_KEYSET_DRIVEN == vParam) {
                setval = SQL_CURSOR_STATIC; /* at least scrollable */
            } else if (SQL_CURSOR_DYNAMIC == vParam) {
                setval = SQL_CURSOR_STATIC; /* at least scrollable */
            }
            if (conn)
                conn->stmtOptions.cursor_type = (SQLUINTEGER)setval;
            else if (stmt) {
                if (SC_get_Result(stmt)) {
                    SC_set_error(
                        stmt, STMT_INVALID_CURSOR_STATE_ERROR,
                        "The attr can't be changed because the cursor is open.",
                        func);
                    return SQL_ERROR;
                }
                stmt->options_orig.cursor_type = stmt->options.cursor_type =
                    (SQLUINTEGER)setval;
            }
            if (setval != vParam)
                changed = TRUE;
            MYPRINTF(0, "-> " FORMAT_LEN "\n", setval);
            break;

        case SQL_KEYSET_SIZE: /* ignored, but saved and returned	*/
            MYLOG(OPENSEARCH_DEBUG, "SQL_KEYSET_SIZE, vParam = " FORMAT_LEN "\n",
                  vParam);

            if (conn)
                conn->stmtOptions.keyset_size = vParam;
            if (stmt) {
                stmt->options_orig.keyset_size = vParam;
                if (!SC_get_Result(stmt))
                    stmt->options.keyset_size = vParam;
                if (stmt->options.keyset_size != (SQLLEN)vParam)
                    changed = TRUE;
            }

            break;

        case SQL_MAX_LENGTH: /* ignored, but saved */
            MYLOG(OPENSEARCH_DEBUG, "SQL_MAX_LENGTH, vParam = " FORMAT_LEN "\n",
                  vParam);
            if (conn)
                conn->stmtOptions.maxLength = vParam;
            if (stmt) {
                stmt->options_orig.maxLength = vParam;
                if (!SC_get_Result(stmt))
                    stmt->options.maxLength = vParam;
                if (stmt->options.maxLength != (SQLLEN)vParam)
                    changed = TRUE;
            }
            break;

        case SQL_MAX_ROWS: /* ignored, but saved */
            MYLOG(OPENSEARCH_DEBUG, "SQL_MAX_ROWS, vParam = " FORMAT_LEN "\n", vParam);
            if (conn)
                conn->stmtOptions.maxRows = vParam;
            if (stmt) {
                stmt->options_orig.maxRows = vParam;
                if (!SC_get_Result(stmt))
                    stmt->options.maxRows = vParam;
                if (stmt->options.maxRows != (SQLLEN)vParam)
                    changed = TRUE;
            }
            break;

        case SQL_NOSCAN: /* ignored */
            MYLOG(OPENSEARCH_DEBUG, "SQL_NOSCAN, vParam = " FORMAT_LEN "\n", vParam);
            break;

        case SQL_QUERY_TIMEOUT: /* ignored */
            MYLOG(OPENSEARCH_DEBUG, "SQL_QUERY_TIMEOUT, vParam = " FORMAT_LEN "\n",
                  vParam);
            if (conn)
                conn->stmtOptions.stmt_timeout = (SQLULEN)vParam;
            if (stmt)
                stmt->options.stmt_timeout = (SQLULEN)vParam;
            break;

        case SQL_RETRIEVE_DATA:
            MYLOG(OPENSEARCH_DEBUG, "SQL_RETRIEVE_DATA, vParam = " FORMAT_LEN "\n",
                  vParam);
            if (conn)
                conn->stmtOptions.retrieve_data = (SQLUINTEGER)vParam;
            if (stmt)
                stmt->options.retrieve_data = (SQLUINTEGER)vParam;
            break;

        case SQL_ROWSET_SIZE:
            MYLOG(OPENSEARCH_DEBUG, "SQL_ROWSET_SIZE, vParam = " FORMAT_LEN "\n",
                  vParam);

            if (vParam < 1) {
                vParam = 1;
                changed = TRUE;
            }

            if (conn)
                conn->ardOptions.size_of_rowset_odbc2 = vParam;
            if (stmt)
                SC_get_ARDF(stmt)->size_of_rowset_odbc2 = vParam;
            break;

        case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
            if (stmt) {
                SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
                             "Simulated positioned update/delete not "
                             "supported.  Use the cursor library.",
                             func);
            }
            if (conn) {
                CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR,
                             "Simulated positioned update/delete not "
                             "supported.  Use the cursor library.",
                             func);
            }
            return SQL_ERROR;

        case SQL_USE_BOOKMARKS:
            if (stmt) {
                MYLOG(
                    OPENSEARCH_DEBUG, "USE_BOOKMARKS %s\n",
                    (vParam == SQL_UB_OFF)
                        ? "off"
                        : ((vParam == SQL_UB_VARIABLE) ? "variable" : "fixed"));
                setval = vParam;
                stmt->options.use_bookmarks = (SQLUINTEGER)setval;
            }
            if (conn)
                conn->stmtOptions.use_bookmarks = (SQLUINTEGER)vParam;
            break;

        case 1204: /* SQL_COPT_SS_PRESERVE_CURSORS ? */
            if (stmt) {
                SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER,
                             "The option may be for MS SQL Server(Set)", func);
            } else if (conn) {
                CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER,
                             "The option may be for MS SQL Server(Set)", func);
            }
            return SQL_ERROR;
        case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
        case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
            if (stmt) {
#ifndef NOT_USED
                if (0 != vParam)
                    changed = TRUE;
                break;
#else
                SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER,
                             "The option may be for MS SQL Server(Set)", func);
#endif /* NOT_USED */
            } else if (conn) {
                CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER,
                             "The option may be for MS SQL Server(Set)", func);
            }
            return SQL_ERROR;
        default: {
            char option[64];

            if (stmt) {
                SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
                             "Unknown statement option (Set)", func);
                SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN,
                              fOption, vParam);
                SC_log_error(func, option, stmt);
            }
            if (conn) {
                CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR,
                             "Unknown statement option (Set)", func);
                SPRINTF_FIXED(option, "fOption=%d, vParam=" FORMAT_ULEN,
                              fOption, vParam);
                CC_log_error(func, option, conn);
            }

            return SQL_ERROR;
        }
    }

    if (changed) {
        if (stmt) {
            SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED,
                         "Requested value changed.", func);
        }
        if (conn) {
            CC_set_error(conn, CONN_OPTION_VALUE_CHANGED,
                         "Requested value changed.", func);
        }
        return SQL_SUCCESS_WITH_INFO;
    } else
        return SQL_SUCCESS;
}