📄 odbc.c
字号:
hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName); retcode = odbc_stat_execute(stmt, "..sp_stored_procedures ", 3, "P@sp_name", szProcName, cbProcName, "P@sp_owner", szSchemaName, cbSchemaName, "O@sp_qualifier", szCatalogName, cbCatalogName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "PROCEDURE_CAT"); odbc_col_setname(stmt, 2, "PROCEDURE_SCHEM"); } ODBC_RETURN_(stmt);}static TDSPARAMINFO*odbc_build_update_params(TDS_STMT * stmt, unsigned int n_row){ unsigned int n; TDSPARAMINFO * params = NULL; struct _drecord *drec_ird; for (n = 0; n < stmt->ird->header.sql_desc_count && n < stmt->ard->header.sql_desc_count; ++n) { TDSPARAMINFO *temp_params; TDSCOLUMN *curcol; drec_ird = &stmt->ird->records[n]; if (drec_ird->sql_desc_updatable == SQL_FALSE) continue; /* we have certainly a parameter */ if (!(temp_params = tds_alloc_param_result(params))) { tds_free_param_results(params); odbc_errs_add(&stmt->errs, "HY001", NULL); return NULL; } params = temp_params; curcol = params->columns[params->num_cols - 1]; if (!tds_alloc_param_data(curcol)) { tds_free_param_results(params); odbc_errs_add(&stmt->errs, "HY001", NULL); return NULL; } tds_strlcpy(curcol->column_name, tds_dstr_cstr(&drec_ird->sql_desc_name), sizeof(curcol->column_name)); curcol->column_namelen = strlen(curcol->column_name); /* TODO use all infos... */ tds_strlcpy(curcol->table_name, tds_dstr_cstr(&drec_ird->sql_desc_base_table_name), sizeof(curcol->table_name)); curcol->table_namelen = strlen(curcol->table_name); switch (sql2tds(stmt, drec_ird, &stmt->ard->records[n], curcol, 1, stmt->ard, n_row)) { case SQL_ERROR: case SQL_NEED_DATA: tds_free_param_results(params); odbc_errs_add(&stmt->errs, "HY001", NULL); return NULL; } } return params;}SQLRETURN ODBC_APISQLSetPos(SQLHSTMT hstmt, SQLSETPOSIROW irow, SQLUSMALLINT fOption, SQLUSMALLINT fLock){ int ret; TDSSOCKET *tds; TDS_CURSOR_OPERATION op; TDSPARAMINFO *params = NULL; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLSetPos(%p, %ld, %d, %d)\n", hstmt, (long) irow, fOption, fLock); if (!stmt->dbc->cursor_support) { odbc_errs_add(&stmt->errs, "HYC00", "SQLSetPos: function not implemented"); ODBC_RETURN(stmt, SQL_ERROR); } /* TODO handle irow == 0 (all rows) */ if (!stmt->cursor) { odbc_errs_add(&stmt->errs, "HY109", NULL); ODBC_RETURN(stmt, SQL_ERROR); } switch (fOption) { case SQL_POSITION: op = TDS_CURSOR_POSITION; break; /* TODO cursor support */ case SQL_REFRESH: default: odbc_errs_add(&stmt->errs, "HY092", NULL); ODBC_RETURN(stmt, SQL_ERROR); break; case SQL_UPDATE: op = TDS_CURSOR_UPDATE; /* prepare paremeters for update */ /* scan all columns and build parameter list */ params = odbc_build_update_params(stmt, irow >= 1 ? irow - 1 : 0); if (!params) { ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); } break; case SQL_DELETE: op = TDS_CURSOR_DELETE; break; case SQL_ADD: op = TDS_CURSOR_INSERT; break; } tds = stmt->dbc->tds_socket; if (!odbc_lock_statement(stmt)) { tds_free_param_results(params); ODBC_RETURN_(stmt); } if (tds_cursor_update(tds, stmt->cursor, op, irow, params) != TDS_SUCCEED) { tds_free_param_results(params); ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); } tds_free_param_results(params); params = NULL; ret = tds_process_simple_query(tds); stmt->dbc->current_statement = NULL; if (ret != TDS_SUCCEED) { ODBC_SAFE_ERROR(stmt); ODBC_RETURN(stmt, SQL_ERROR); } ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLTablePrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName){ int retcode; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "SQLTablePrivileges(%p, %p, %d, %p, %d, %p, %d)\n", hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName); retcode = odbc_stat_execute(stmt, "sp_table_privileges ", 3, "O@table_qualifier", szCatalogName, cbCatalogName, "P@table_owner", szSchemaName, cbSchemaName, "P@table_name", szTableName, cbTableName); if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) { odbc_col_setname(stmt, 1, "TABLE_CAT"); odbc_col_setname(stmt, 2, "TABLE_SCHEM"); } ODBC_RETURN_(stmt);}#if (ODBCVER >= 0x0300)SQLRETURN ODBC_APISQLSetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength){ SQLINTEGER i_val = (SQLINTEGER) (TDS_INTPTR) Value; INIT_HENV; tdsdump_log(TDS_DBG_FUNC, "SQLSetEnvAttr(%p, %d, %p, %d)\n", henv, (int)Attribute, Value, (int)StringLength); switch (Attribute) { case SQL_ATTR_CONNECTION_POOLING: case SQL_ATTR_CP_MATCH: odbc_errs_add(&env->errs, "HYC00", NULL); ODBC_RETURN(env, SQL_ERROR); break; case SQL_ATTR_ODBC_VERSION: switch (i_val) { case SQL_OV_ODBC3: case SQL_OV_ODBC2: break; default: odbc_errs_add(&env->errs, "HY024", NULL); ODBC_RETURN(env, SQL_ERROR); } env->attr.odbc_version = i_val; ODBC_RETURN_(env); break; case SQL_ATTR_OUTPUT_NTS: env->attr.output_nts = i_val; /* TODO - Make this really work */ env->attr.output_nts = SQL_TRUE; ODBC_RETURN_(env); break; } odbc_errs_add(&env->errs, "HY092", NULL); ODBC_RETURN(env, SQL_ERROR);}SQLRETURN ODBC_APISQLGetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength){ size_t size; void *src; INIT_HENV; tdsdump_log(TDS_DBG_FUNC, "SQLGetEnvAttr(%p, %d, %p, %d, %p)\n", henv, (int)Attribute, Value, (int)BufferLength, StringLength); switch (Attribute) { case SQL_ATTR_CONNECTION_POOLING: src = &env->attr.connection_pooling; size = sizeof(env->attr.connection_pooling); break; case SQL_ATTR_CP_MATCH: src = &env->attr.cp_match; size = sizeof(env->attr.cp_match); break; case SQL_ATTR_ODBC_VERSION: src = &env->attr.odbc_version; size = sizeof(env->attr.odbc_version); break; case SQL_ATTR_OUTPUT_NTS: /* TODO handle output_nts flags */ env->attr.output_nts = SQL_TRUE; src = &env->attr.output_nts; size = sizeof(env->attr.output_nts); break; default: odbc_errs_add(&env->errs, "HY092", NULL); ODBC_RETURN(env, SQL_ERROR); break; } if (StringLength) { *StringLength = size; } memcpy(Value, src, size); ODBC_RETURN_(env);}#endifstatic SQLRETURN_SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue){ TDS_DESC *apd, *ipd; struct _drecord *drec; SQLSMALLINT orig_apd_size, orig_ipd_size; int is_numeric = 0; INIT_HSTMT; tdsdump_log(TDS_DBG_FUNC, "_SQLBindParameter(%p, %u, %d, %d, %d, %u, %d, %p, %d, %p)\n", hstmt, (unsigned short)ipar, (int)fParamType, (int)fCType, (int)fSqlType, (unsigned int)cbColDef, (int)ibScale, rgbValue, (int)cbValueMax, pcbValue);#ifdef TDS_NO_DM /* TODO - more error checking ... XXX smurph */ /* Check param type */ switch (fParamType) { case SQL_PARAM_INPUT: case SQL_PARAM_INPUT_OUTPUT: case SQL_PARAM_OUTPUT: break; default: odbc_errs_add(&stmt->errs, "HY105", NULL); ODBC_RETURN(stmt, SQL_ERROR); } /* Check max buffer length */ if (cbValueMax < 0) { odbc_errs_add(&stmt->errs, "HY090", NULL); ODBC_RETURN(stmt, SQL_ERROR); }#endif /* check cbColDef and ibScale */ if (fSqlType == SQL_DECIMAL || fSqlType == SQL_NUMERIC) { is_numeric = 1; if (cbColDef < 1 || cbColDef > 38) { odbc_errs_add(&stmt->errs, "HY104", "Invalid precision value"); ODBC_RETURN(stmt, SQL_ERROR); } if (ibScale < 0 || ibScale > cbColDef) { odbc_errs_add(&stmt->errs, "HY104", "Invalid scale value"); ODBC_RETURN(stmt, SQL_ERROR); } } /* Check parameter number */ if (ipar <= 0 || ipar > 4000) { odbc_errs_add(&stmt->errs, "07009", NULL); ODBC_RETURN(stmt, SQL_ERROR); } /* fill APD related fields */ apd = stmt->apd; orig_apd_size = apd->header.sql_desc_count; if (ipar > apd->header.sql_desc_count && desc_alloc_records(apd, ipar) != SQL_SUCCESS) { odbc_errs_add(&stmt->errs, "HY001", NULL); ODBC_RETURN(stmt, SQL_ERROR); } drec = &apd->records[ipar - 1]; if (odbc_set_concise_c_type(fCType, drec, 0) != SQL_SUCCESS) { desc_alloc_records(apd, orig_apd_size); odbc_errs_add(&stmt->errs, "HY004", NULL); ODBC_RETURN(stmt, SQL_ERROR); } stmt->need_reprepare = 1; /* TODO other types ?? handle SQL_C_DEFAULT */ if (drec->sql_desc_type == SQL_C_CHAR || drec->sql_desc_type == SQL_C_BINARY) drec->sql_desc_octet_length = cbValueMax; drec->sql_desc_indicator_ptr = pcbValue; drec->sql_desc_octet_length_ptr = pcbValue; drec->sql_desc_data_ptr = (char *) rgbValue; /* field IPD related fields */ ipd = stmt->ipd; orig_ipd_size = ipd->header.sql_desc_count; if (ipar > ipd->header.sql_desc_count && desc_alloc_records(ipd, ipar) != SQL_SUCCESS) { desc_alloc_records(apd, orig_apd_size); odbc_errs_add(&stmt->errs, "HY001", NULL); ODBC_RETURN(stmt, SQL_ERROR); } drec = &ipd->records[ipar - 1]; drec->sql_desc_parameter_type = fParamType; if (odbc_set_concise_sql_type(fSqlType, drec, 0) != SQL_SUCCESS) { desc_alloc_records(ipd, orig_ipd_size); desc_alloc_records(apd, orig_apd_size); odbc_errs_add(&stmt->errs, "HY004", NULL); ODBC_RETURN(stmt, SQL_ERROR); } if (is_numeric) { drec->sql_desc_precision = cbColDef; drec->sql_desc_scale = ibScale; } else { drec->sql_desc_length = cbColDef; } ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue){ tdsdump_log(TDS_DBG_FUNC, "SQLBindParameter(%p, %u, %d, %d, %d, %u, %d, %p, %d, %p)\n", hstmt, (unsigned)ipar, fParamType, fCType, (int)fSqlType, (unsigned)cbColDef, ibScale, rgbValue, (int)cbValueMax, pcbValue); return _SQLBindParameter(hstmt, ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, cbValueMax, pcbValue);}/* compatibility with X/Open */SQLRETURN ODBC_APISQLBindParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fCType, SQLSMALLINT fSqlType, SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN FAR * pcbValue){ tdsdump_log(TDS_DBG_FUNC, "SQLBindParam(%p, %d, %d, %d, %u, %d, %p, %p)\n", hstmt, ipar, fCType, fSqlType, (unsigned)cbColDef, ibScale, rgbValue, pcbValue); return _SQLBindParameter(hstmt, ipar, SQL_PARAM_INPUT, fCType, fSqlType, cbColDef, ibScale, rgbValue, 0, pcbValue);}#if (ODBCVER >= 0x0300)SQLRETURN ODBC_APISQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * OutputHandle){ tdsdump_log(TDS_DBG_FUNC, "SQLAllocHandle(%d, %p, %p)\n", HandleType, InputHandle, OutputHandle); switch (HandleType) { case SQL_HANDLE_STMT: return _SQLAllocStmt(InputHandle, OutputHandle); break; case SQL_HANDLE_DBC: return _SQLAllocConnect(InputHandle, OutputHandle); break; case SQL_HANDLE_ENV: return _SQLAllocEnv(OutputHandle); break; case SQL_HANDLE_DESC: return _SQLAllocDesc(InputHandle, OutputHandle); break; } /* TODO HY092 error */ return SQL_ERROR;}#endifstatic SQLRETURN_SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc){ TDS_DBC *dbc; INIT_HENV; tdsdump_log(TDS_DBG_FUNC, "_SQLAllocConnect(%p, %p)\n", henv, phdbc); dbc = (TDS_DBC *) calloc(1, sizeof(TDS_DBC)); if (!dbc) { odbc_errs_add(&env->errs, "HY001", NULL); ODBC_RETURN(env, SQL_ERROR); } dbc->htype = SQL_HANDLE_DBC; dbc->env = env; tds_dstr_init(&dbc->server); tds_dstr_init(&dbc->dsn); dbc->attr.cursor_type = SQL_CURSOR_FORWARD_ONLY; dbc->attr.access_mode = SQL_MODE_READ_WRITE; dbc->attr.async_enable = SQL_ASYNC_ENABLE_OFF; dbc->attr.auto_ipd = SQL_FALSE; /* * spinellia@acm.org * after login is enabled autocommit */ dbc->attr.autocommit = SQL_AUTOCOMMIT_ON; dbc->attr.connection_dead = SQL_CD_TRUE; /* No connection yet */ dbc->attr.connection_timeout = 0; /* This is set in the environment change function */ tds_dstr_init(&dbc->attr.current_catalog); dbc->attr.login_timeout = 0; /* TODO */ dbc->attr.metadata_id = SQL_FALSE; dbc->attr.odbc_cursors = SQL_CUR_USE_IF_NEEDED; dbc->attr.packet_size = 0; dbc->attr.quite_mode = NULL; /* We don't support GUI dialogs yet */#ifdef TDS_NO_DM dbc->attr.trace = SQL_OPT_TRACE_OFF; tds_dstr_init(&dbc->attr.tracefile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -