RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle, SQLUSMALLINT InfoType, PTR InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { CSTR func = "SQLGetInfoW"; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; RETCODE ret; ENTER_CONN_CS(conn); CC_set_in_unicode_driver(conn); CC_clear_error(conn); #if (ODBCVER >= 0x0300) mylog("[%s(30)]", func); if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength)) == SQL_ERROR) { if (conn->driver_version >= 0x0300) { CC_clear_error(conn); ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength); } } if (SQL_ERROR == ret) CC_log_error("SQLGetInfoW(30)", "", conn); #else mylog("[%s]", func); ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength); if (SQL_ERROR == ret) CC_log_error("SQLGetInfoW", "", conn); #endif LEAVE_CONN_CS(conn); return ret; }
RETCODE SQL_API PG_SQLAllocStmt(HDBC hdbc, HSTMT FAR *phstmt) { static char* const func="SQLAllocStmt"; ConnectionClass *conn = (ConnectionClass *) hdbc; StatementClass *stmt; mylog("%s: entering...\n", func); if( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } stmt = SC_Constructor(); mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt); if ( ! stmt) { CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "No more memory to allocate a further SQL-statement"); *phstmt = SQL_NULL_HSTMT; CC_log_error(func, "", conn); return SQL_ERROR; } if ( ! CC_add_statement(conn, stmt)) { CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "Maximum number of connections exceeded."); CC_log_error(func, "", conn); SC_Destructor(stmt); *phstmt = SQL_NULL_HSTMT; return SQL_ERROR; } *phstmt = (HSTMT) stmt; /* Copy default statement options based from Connection options */ stmt->options = conn->stmtOptions; /* Save the handle for later */ stmt->phstmt = phstmt; return SQL_SUCCESS; }
RETCODE SQL_API SQLGetInfo(HDBC ConnectionHandle, SQLUSMALLINT InfoType, PTR InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { CSTR func = "SQLGetInfo"; RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; CC_examine_global_transaction(conn); ENTER_CONN_CS(conn); CC_clear_error(conn); #if (ODBCVER >= 0x0300) mylog("[%s(30)]", func); if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength)) == SQL_ERROR) { if (conn->driver_version >= 0x0300) { CC_clear_error(conn); ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength); goto cleanup; } } if (SQL_ERROR == ret) CC_log_error("SQLGetInfo(30)", "", conn); #else mylog("[%s]", func); if (ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength), SQL_ERROR == ret) CC_log_error(func, "", conn); #endif cleanup: LEAVE_CONN_CS(conn); return ret; }
RETCODE SQL_API SQLGetInfoW(HDBC ConnectionHandle, SQLUSMALLINT InfoType, PTR InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { CSTR func = "SQLGetInfoW"; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; RETCODE ret; CC_examine_global_transaction(conn); ENTER_CONN_CS(conn); CC_set_in_unicode_driver(conn); CC_clear_error(conn); mylog("[%s]", func); if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength)) == SQL_ERROR) CC_log_error("SQLGetInfoW", "", conn); LEAVE_CONN_CS(conn); return ret; }
void SC_log_error(char *func, char *desc, StatementClass *self) { #ifdef PRN_NULLCHECK #define nullcheck(a) (a ? a : "(NULL)") #endif if (self) { qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message)); mylog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->__error_number, nullcheck(self->__error_message)); qlog(" ------------------------------------------------------------\n"); qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result); qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal); qlog(" bindings=%u, bindings_allocated=%d\n", self->bindings, self->bindings_allocated); qlog(" parameters=%u, parameters_allocated=%d\n", self->parameters, self->parameters_allocated); qlog(" statement_type=%d, statement='%s'\n", self->statement_type, nullcheck(self->statement)); qlog(" stmt_with_params='%s'\n", nullcheck(self->stmt_with_params)); qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data); qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd); qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->options.maxRows, self->options.rowset_size, self->options.keyset_size, self->options.cursor_type, self->options.scroll_concurrency); qlog(" cursor_name='%s'\n", nullcheck(self->cursor_name)); qlog(" ----------------QResult Info -------------------------------\n"); if (self->result) { QResultClass *res = self->result; qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn); qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, nullcheck(res->cursor)); qlog(" message='%s', command='%s', notice='%s'\n", nullcheck(res->message), nullcheck(res->command), nullcheck(res->notice)); qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples); } /* Log the connection error if there is one */ CC_log_error(func, desc, self->hdbc); } else qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc); #undef PRN_NULLCHECK }
RETCODE SQL_API PGAPI_Transact( HENV henv, HDBC hdbc, SQLUSMALLINT fType) { CSTR func = "PGAPI_Transact"; ConnectionClass *conn; char ok; int lf; mylog("entering %s: hdbc=%p, henv=%p\n", func, hdbc, henv); if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } /* * If hdbc is null and henv is valid, it means transact all * connections on that henv. */ if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) { ConnectionClass * const *conns = getConnList(); const int conn_count = getConnCount(); for (lf = 0; lf < conn_count; lf++) { conn = conns[lf]; if (conn && CC_get_env(conn) == henv) if (PGAPI_Transact(henv, (HDBC) conn, fType) != SQL_SUCCESS) return SQL_ERROR; } return SQL_SUCCESS; } conn = (ConnectionClass *) hdbc; if (fType != SQL_COMMIT && fType != SQL_ROLLBACK) { CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "PGAPI_Transact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter", func); return SQL_ERROR; } /* If manual commit and in transaction, then proceed. */ if (CC_loves_visible_trans(conn) && CC_is_in_trans(conn)) { mylog("PGAPI_Transact: sending on conn %p '%d'\n", conn, fType); ok = (SQL_COMMIT == fType) ? CC_commit(conn) : CC_abort(conn); if (!ok) { /* error msg will be in the connection */ CC_on_abort(conn, NO_TRANS); CC_log_error(func, "", conn); return SQL_ERROR; } } return SQL_SUCCESS; }
RETCODE SQL_API PGAPI_DriverConnect( HDBC hdbc, HWND hwnd, const SQLCHAR FAR * szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR FAR * szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT FAR * pcbConnStrOut, SQLUSMALLINT fDriverCompletion) { CSTR func = "PGAPI_DriverConnect"; ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; #ifdef WIN32 RETCODE dialog_result; #endif BOOL paramRequired, didUI = FALSE; RETCODE result; char *connStrIn = NULL; char connStrOut[MAX_CONNECT_STRING]; int retval; char salt[5]; char password_required = AUTH_REQ_OK; ssize_t len = 0; SQLSMALLINT lenStrout; mylog("%s: entering...\n", func); if (!conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0); #ifdef FORCE_PASSWORD_DISPLAY mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); #else if (get_qlog() || get_mylog()) { char *hide_str = hide_password(connStrIn); mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str)); qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion); if (hide_str) free(hide_str); } #endif /* FORCE_PASSWORD_DISPLAY */ ci = &(conn->connInfo); /* Parse the connect string and fill in conninfo for this hdbc. */ dconn_get_connect_attributes(connStrIn, ci); /* * If the ConnInfo in the hdbc is missing anything, this function will * fill them in from the registry (assuming of course there is a DSN * given -- if not, it does nothing!) */ getDSNinfo(ci, CONN_DONT_OVERWRITE); dconn_get_common_attributes(connStrIn, ci); logs_on_off(1, ci->drivers.debug, ci->drivers.commlog); if (connStrIn) { free(connStrIn); connStrIn = NULL; } /* Fill in any default parameters if they are not there. */ getDSNdefaults(ci); /* initialize pg_version */ CC_initialize_pg_version(conn); memset(salt, 0, sizeof(salt)); #ifdef WIN32 dialog: #endif ci->focus_password = password_required; inolog("DriverCompletion=%d\n", fDriverCompletion); switch (fDriverCompletion) { #ifdef WIN32 case SQL_DRIVER_PROMPT: dialog_result = dconn_DoDialog(hwnd, ci); didUI = TRUE; if (dialog_result != SQL_SUCCESS) return dialog_result; break; case SQL_DRIVER_COMPLETE_REQUIRED: /* Fall through */ case SQL_DRIVER_COMPLETE: paramRequired = password_required; /* Password is not a required parameter. */ if (ci->database[0] == '\0') paramRequired = TRUE; else if (ci->port[0] == '\0') paramRequired = TRUE; #ifdef WIN32 else if (ci->server[0] == '\0') paramRequired = TRUE; #endif /* WIN32 */ if (paramRequired) { dialog_result = dconn_DoDialog(hwnd, ci); didUI = TRUE; if (dialog_result != SQL_SUCCESS) return dialog_result; } break; #else case SQL_DRIVER_PROMPT: case SQL_DRIVER_COMPLETE: case SQL_DRIVER_COMPLETE_REQUIRED: #endif case SQL_DRIVER_NOPROMPT: break; } /* * Password is not a required parameter unless authentication asks for * it. For now, I think it's better to just let the application ask * over and over until a password is entered (the user can always hit * Cancel to get out) */ paramRequired = FALSE; if (ci->database[0] == '\0') paramRequired = TRUE; else if (ci->port[0] == '\0') paramRequired = TRUE; #ifdef WIN32 else if (ci->server[0] == '\0') paramRequired = TRUE; #endif /* WIN32 */ if (paramRequired) { if (didUI) return SQL_NO_DATA_FOUND; CC_set_error(conn, CONN_OPENDB_ERROR, "connction string lacks some options", func); return SQL_ERROR; } inolog("before CC_connect\n"); /* do the actual connect */ retval = CC_connect(conn, password_required, salt); if (retval < 0) { /* need a password */ if (fDriverCompletion == SQL_DRIVER_NOPROMPT) { CC_log_error(func, "Need password but Driver_NoPrompt", conn); return SQL_ERROR; /* need a password but not allowed to * prompt so error */ } else { #ifdef WIN32 password_required = -retval; goto dialog; #else return SQL_ERROR; /* until a better solution is found. */ #endif } } else if (retval == 0) { /* error msg filled in above */ CC_log_error(func, "Error from CC_Connect", conn); return SQL_ERROR; } /* * Create the Output Connection String */ result = SQL_SUCCESS; lenStrout = cbConnStrOutMax; if (conn->ms_jet && lenStrout > 255) lenStrout = 255; makeConnectString(connStrOut, ci, lenStrout); len = strlen(connStrOut); if (szConnStrOut) { /* * Return the completed string to the caller. The correct method * is to only construct the connect string if a dialog was put up, * otherwise, it should just copy the connection input string to * the output. However, it seems ok to just always construct an * output string. There are possible bad side effects on working * applications (Access) by implementing the correct behavior, * anyway. */ /*strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);*/ strncpy(szConnStrOut, connStrOut, cbConnStrOutMax); if (len >= cbConnStrOutMax) { int clen; for (clen = cbConnStrOutMax - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--) szConnStrOut[clen] = '\0'; result = SQL_SUCCESS_WITH_INFO; CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.", func); } } if (pcbConnStrOut) *pcbConnStrOut = (SQLSMALLINT) len; #ifdef FORCE_PASSWORD_DISPLAY if (cbConnStrOutMax > 0) { mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(szConnStrOut), len, cbConnStrOutMax); qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(szConnStrOut)); } #else if (get_qlog() || get_mylog()) { char *hide_str = NULL; if (cbConnStrOutMax > 0) hide_str = hide_password(szConnStrOut); mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax); qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str)); if (hide_str) free(hide_str); } #endif /* FORCE_PASSWORD_DISPLAY */ if (connStrIn) free(connStrIn); mylog("PGAPI_DriverConnect: returning %d\n", result); return result; }
RETCODE set_statement_option(ConnectionClass *conn, StatementClass *stmt, UWORD fOption, UDWORD vParam) { static char *func="set_statement_option"; char changed = FALSE; switch(fOption) { case SQL_ASYNC_ENABLE:/* ignored */ break; case SQL_BIND_TYPE: /* now support multi-column and multi-row binding */ if (conn) conn->stmtOptions.bind_size = vParam; if (stmt) stmt->options.bind_size = vParam; break; case SQL_CONCURRENCY: /* positioned update isn't supported so cursor concurrency is read-only */ if (conn) conn->stmtOptions.scroll_concurrency = vParam; if (stmt) stmt->options.scroll_concurrency = vParam; break; /* if (globals.lie) { if (conn) conn->stmtOptions.scroll_concurrency = vParam; if (stmt) stmt->options.scroll_concurrency = vParam; } else { if (conn) conn->stmtOptions.scroll_concurrency = SQL_CONCUR_READ_ONLY; if (stmt) stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; if (vParam != SQL_CONCUR_READ_ONLY) changed = TRUE; } break; */ case SQL_CURSOR_TYPE: /* if declare/fetch, then type can only be forward. otherwise, it can only be forward or static. */ mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam); if (globals.lie) { if (conn) conn->stmtOptions.cursor_type = vParam; if (stmt) stmt->options.cursor_type = vParam; } else { if (globals.use_declarefetch) { if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY; if (stmt) stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY; if (vParam != SQL_CURSOR_FORWARD_ONLY) changed = TRUE; } else { if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC) { if (conn) conn->stmtOptions.cursor_type = vParam; /*// valid type */ if (stmt) stmt->options.cursor_type = vParam; /*// valid type */ } else { if (conn) conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC; if (stmt) stmt->options.cursor_type = SQL_CURSOR_STATIC; changed = TRUE; } } } break; case SQL_KEYSET_SIZE: /* ignored, but saved and returned */ mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam); if (conn) conn->stmtOptions.keyset_size = vParam; if (stmt) stmt->options.keyset_size = vParam; break; /* if (globals.lie) stmt->keyset_size = vParam; else { stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errormsg = "Driver does not support keyset size option"; SC_log_error(func, "", stmt); return SQL_ERROR; } */ case SQL_MAX_LENGTH:/* ignored, but saved */ mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam); if (conn) conn->stmtOptions.maxLength = vParam; if (stmt) stmt->options.maxLength = vParam; break; case SQL_MAX_ROWS: /* ignored, but saved */ mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam); if (conn) conn->stmtOptions.maxRows = vParam; if (stmt) stmt->options.maxRows = vParam; break; case SQL_NOSCAN: /* ignored */ mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam); break; case SQL_QUERY_TIMEOUT: /* ignored */ mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam); /*// "0" returned in SQLGetStmtOption */ break; case SQL_RETRIEVE_DATA: /* ignored, but saved */ mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam); if (conn) conn->stmtOptions.retrieve_data = vParam; if (stmt) stmt->options.retrieve_data = vParam; break; case SQL_ROWSET_SIZE: mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam); /* Save old rowset size for SQLExtendedFetch purposes If the rowset_size is being changed since the last call to fetch rows. */ if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0 ) stmt->save_rowset_size = stmt->options.rowset_size; if (vParam < 1) { vParam = 1; changed = TRUE; } if (conn) conn->stmtOptions.rowset_size = vParam; if (stmt) stmt->options.rowset_size = vParam; break; case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */ if (stmt) { stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; SC_log_error(func, "", stmt); } if (conn) { conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR; conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; CC_log_error(func, "", conn); } return SQL_ERROR; case SQL_USE_BOOKMARKS: if (stmt) stmt->options.use_bookmarks = vParam; if (conn) conn->stmtOptions.use_bookmarks = vParam; break; /* * added to be nice to OpenOffice */ case /*SQL_ATTR_CURSOR_SENSITIVITY*/ 65534: break; default: { char option[64]; if (stmt) { stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errormsg = "Unknown statement option (Set)"; sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); SC_log_error(func, option, stmt); } if (conn) { conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR; conn->errormsg = "Unknown statement option (Set)"; sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); CC_log_error(func, option, conn); } return SQL_ERROR; } } if (changed) { if (stmt) { stmt->errormsg = "Requested value changed."; stmt->errornumber = STMT_OPTION_VALUE_CHANGED; } if (conn) { conn->errormsg = "Requested value changed."; conn->errornumber = STMT_OPTION_VALUE_CHANGED; } return SQL_SUCCESS_WITH_INFO; } else return SQL_SUCCESS; }
/* This function just can tell you whether you are in Autcommit mode or not */ RETCODE SQL_API SQLGetConnectOption( HDBC hdbc, UWORD fOption, PTR pvParam) { static char *func="SQLGetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("%s: entering...\n", func); if (! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } switch (fOption) { case SQL_ACCESS_MODE:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = SQL_MODE_READ_WRITE; break; case SQL_AUTOCOMMIT: *((UDWORD *)pvParam) = (UDWORD)( CC_is_in_autocommit(conn) ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF); break; case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */ if(pvParam) { ((char*)pvParam)[0]='\0'; } break; case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */ *((UDWORD *) pvParam) = 0; break; case SQL_PACKET_SIZE: /* NOT SUPPORTED */ *((UDWORD *) pvParam) = globals.socket_buffersize; break; case SQL_QUIET_MODE:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = (UDWORD) NULL; break; case SQL_TXN_ISOLATION:/* NOT SUPPORTED */ *((UDWORD *) pvParam) = SQL_TXN_SERIALIZABLE; break; /* These options should be handled by driver manager */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: case SQL_OPT_TRACEFILE: case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn); break; default: { char option[64]; conn->errormsg = "Unknown connect option (Get)"; conn->errornumber = CONN_UNSUPPORTED_OPTION; sprintf(option, "fOption=%d", fOption); CC_log_error(func, option, conn); return SQL_ERROR; break; } } return SQL_SUCCESS; }
/* Implements only SQL_AUTOCOMMIT */ RETCODE SQL_API SQLSetConnectOption( HDBC hdbc, UWORD fOption, SQLULEN vParam) { static char *func="SQLSetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; char changed = FALSE; RETCODE retval; int i; mylog("%s: entering...\n", func); if ( ! conn) { CC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } switch (fOption) { /* Statement Options -- (apply to all stmts on the connection and become defaults for new stmts) */ case SQL_ASYNC_ENABLE: case SQL_BIND_TYPE: case SQL_CONCURRENCY: case SQL_CURSOR_TYPE: case SQL_KEYSET_SIZE: case SQL_MAX_LENGTH: case SQL_MAX_ROWS: case SQL_NOSCAN: case SQL_QUERY_TIMEOUT: case SQL_RETRIEVE_DATA: case SQL_ROWSET_SIZE: case SQL_SIMULATE_CURSOR: case SQL_USE_BOOKMARKS: /* Affect all current Statements */ for (i = 0; i < conn->num_stmts; i++) { if ( conn->stmts[i]) { set_statement_option(NULL, conn->stmts[i], fOption, vParam); } } /* Become the default for all future statements on this connection */ retval = set_statement_option(conn, NULL, fOption, vParam); if (retval == SQL_SUCCESS_WITH_INFO) changed = TRUE; else if (retval == SQL_ERROR) return SQL_ERROR; break; /**********************************/ /***** Connection Options *******/ /**********************************/ case SQL_ACCESS_MODE: /* ignored */ break; case SQL_AUTOCOMMIT: /* Since we are almost always in a transaction, this is now ok. Even if we were, the logic will handle it by sending a commit after the statement. if (CC_is_in_trans(conn)) { conn->errormsg = "Cannot switch commit mode while a transaction is in progres"; conn->errornumber = CONN_TRANSACT_IN_PROGRES; CC_log_error(func, "", conn); return SQL_ERROR; } */ mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); switch(vParam) { case SQL_AUTOCOMMIT_OFF: CC_set_autocommit_off(conn); break; case SQL_AUTOCOMMIT_ON: CC_set_autocommit_on(conn); break; default: conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT"; conn->errornumber = CONN_INVALID_ARGUMENT_NO; CC_log_error(func, "", conn); return SQL_ERROR; } break; case SQL_CURRENT_QUALIFIER: /* ignored */ break; case SQL_LOGIN_TIMEOUT: /* ignored */ break; case SQL_PACKET_SIZE: /* ignored */ break; case SQL_QUIET_MODE: /* ignored */ break; case SQL_TXN_ISOLATION: /* ignored */ break; /* These options should be handled by driver manager */ case SQL_ODBC_CURSORS: case SQL_OPT_TRACE: case SQL_OPT_TRACEFILE: case SQL_TRANSLATE_DLL: case SQL_TRANSLATE_OPTION: CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn); break; default: { char option[64]; conn->errormsg = "Unknown connect option (Set)"; conn->errornumber = CONN_UNSUPPORTED_OPTION; sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam); CC_log_error(func, option, conn); return SQL_ERROR; } } if (changed) { conn->errornumber = CONN_OPTION_VALUE_CHANGED; conn->errormsg = "Requested value changed."; return SQL_SUCCESS_WITH_INFO; } else return SQL_SUCCESS; }