⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odbc.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif	tds_dstr_init(&dbc->attr.translate_lib);	dbc->attr.translate_option = 0;	dbc->attr.txn_isolation = SQL_TXN_READ_COMMITTED;	*phdbc = (SQLHDBC) dbc;	ODBC_RETURN_(env);}SQLRETURN ODBC_APISQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc){	tdsdump_log(TDS_DBG_FUNC, "SQLAllocConnect(%p, %p)\n", henv, phdbc);	odbc_errs_reset(&((TDS_ENV *) henv)->errs);	return _SQLAllocConnect(henv, phdbc);}static SQLRETURN_SQLAllocEnv(SQLHENV FAR * phenv){	TDS_ENV *env;	TDSCONTEXT *ctx;	tdsdump_log(TDS_DBG_FUNC, "_SQLAllocEnv(%p)\n", 			phenv);	env = (TDS_ENV *) calloc(1, sizeof(TDS_ENV));	if (!env)		return SQL_ERROR;	env->htype = SQL_HANDLE_ENV;	env->attr.odbc_version = SQL_OV_ODBC2;	/* TODO use it */	env->attr.output_nts = SQL_TRUE;	ctx = tds_alloc_context(env);	if (!ctx) {		free(env);		return SQL_ERROR;	}	env->tds_ctx = ctx;	ctx->msg_handler = odbc_errmsg_handler;	ctx->err_handler = odbc_errmsg_handler;	/* ODBC has its own format */	free(ctx->locale->date_fmt);	ctx->locale->date_fmt = strdup("%Y-%m-%d %H:%M:%S.%z");	*phenv = (SQLHENV) env;	return SQL_SUCCESS;}SQLRETURN ODBC_APISQLAllocEnv(SQLHENV FAR * phenv){	tdsdump_log(TDS_DBG_FUNC, "SQLAllocEnv(%p)\n", phenv);	return _SQLAllocEnv(phenv);}static SQLRETURN_SQLAllocDesc(SQLHDBC hdbc, SQLHDESC FAR * phdesc){	int i;	INIT_HDBC;	tdsdump_log(TDS_DBG_FUNC, "_SQLAllocDesc(%p, %p)\n", hdbc, phdesc);	for (i = 0; i < TDS_MAX_APP_DESC; ++i) {		if (dbc->uad[i] == NULL) {			TDS_DESC *desc = desc_alloc(dbc, DESC_ARD, SQL_DESC_ALLOC_USER);			if (desc == NULL) {				odbc_errs_add(&dbc->errs, "HY001", NULL);				ODBC_RETURN(dbc, SQL_ERROR);			}			dbc->uad[i] = desc;			*phdesc = (SQLHDESC) desc;			ODBC_RETURN_(dbc);		}	}	odbc_errs_add(&dbc->errs, "HY014", NULL);	ODBC_RETURN(dbc, SQL_ERROR);}static SQLRETURN_SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt){	TDS_STMT *stmt;	char *pstr;	INIT_HDBC;	tdsdump_log(TDS_DBG_FUNC, "_SQLAllocStmt(%p, %p)\n", hdbc, phstmt);	stmt = (TDS_STMT *) calloc(1, sizeof(TDS_STMT));	if (!stmt) {		odbc_errs_add(&dbc->errs, "HY001", NULL);		ODBC_RETURN(dbc, SQL_ERROR);	}	tds_dstr_init(&stmt->cursor_name);	stmt->htype = SQL_HANDLE_STMT;	stmt->dbc = dbc;	stmt->num_param_rows = 1;	pstr = NULL;	/* TODO test initial cursor ... */	if (asprintf(&pstr, "SQL_CUR%lx", (unsigned long) stmt) < 0 || !tds_dstr_set(&stmt->cursor_name, pstr)) {		free(stmt);		free(pstr);		odbc_errs_add(&dbc->errs, "HY001", NULL);		ODBC_RETURN(dbc, SQL_ERROR);	}	/* do not free pstr tds_dstr_set do it if necessary */	/* allocate descriptors */	stmt->ird = desc_alloc(stmt, DESC_IRD, SQL_DESC_ALLOC_AUTO);	stmt->ard = desc_alloc(stmt, DESC_ARD, SQL_DESC_ALLOC_AUTO);	stmt->ipd = desc_alloc(stmt, DESC_IPD, SQL_DESC_ALLOC_AUTO);	stmt->apd = desc_alloc(stmt, DESC_APD, SQL_DESC_ALLOC_AUTO);	if (!stmt->ird || !stmt->ard || !stmt->ipd || !stmt->apd) {		tds_dstr_free(&stmt->cursor_name);		desc_free(stmt->ird);		desc_free(stmt->ard);		desc_free(stmt->ipd);		desc_free(stmt->apd);		free(stmt);		odbc_errs_add(&dbc->errs, "HY001", NULL);		ODBC_RETURN(dbc, SQL_ERROR);	}	/* save original ARD and APD */	stmt->orig_apd = stmt->apd;	stmt->orig_ard = stmt->ard;	/* set the default statement attributes *//*	stmt->attr.app_param_desc = stmt->apd; *//*	stmt->attr.app_row_desc = stmt->ard; */	stmt->attr.async_enable = SQL_ASYNC_ENABLE_OFF;	stmt->attr.concurrency = SQL_CONCUR_READ_ONLY;	stmt->attr.cursor_scrollable = SQL_NONSCROLLABLE;	stmt->attr.cursor_sensitivity = SQL_INSENSITIVE;	stmt->attr.cursor_type = SQL_CURSOR_FORWARD_ONLY;	/* TODO ?? why two attributes */	stmt->attr.enable_auto_ipd = dbc->attr.auto_ipd = SQL_FALSE;	stmt->attr.fetch_bookmark_ptr = NULL;/*	stmt->attr.imp_param_desc = stmt->ipd; *//*	stmt->attr.imp_row_desc = stmt->ird; */	stmt->attr.keyset_size = 0;	stmt->attr.max_length = 0;	stmt->attr.max_rows = 0;	stmt->attr.metadata_id = dbc->attr.metadata_id;	/* TODO check this flag in prepare_call */	stmt->attr.noscan = SQL_NOSCAN_OFF;	assert(stmt->apd->header.sql_desc_bind_offset_ptr == NULL);	assert(stmt->apd->header.sql_desc_bind_type == SQL_PARAM_BIND_BY_COLUMN);	assert(stmt->apd->header.sql_desc_array_status_ptr == NULL);	assert(stmt->ipd->header.sql_desc_array_status_ptr == NULL);	assert(stmt->ipd->header.sql_desc_rows_processed_ptr == NULL);	assert(stmt->apd->header.sql_desc_array_size == 1);	stmt->attr.query_timeout = DEFAULT_QUERY_TIMEOUT;	stmt->attr.retrieve_data = SQL_RD_ON;	assert(stmt->ard->header.sql_desc_array_size == 1);	assert(stmt->ard->header.sql_desc_bind_offset_ptr == NULL);	assert(stmt->ard->header.sql_desc_bind_type == SQL_BIND_BY_COLUMN);	stmt->attr.row_number = 0;	assert(stmt->ard->header.sql_desc_array_status_ptr == NULL);	assert(stmt->ird->header.sql_desc_array_status_ptr == NULL);	assert(stmt->ird->header.sql_desc_rows_processed_ptr == NULL);	stmt->attr.simulate_cursor = SQL_SC_NON_UNIQUE;	stmt->attr.use_bookmarks = SQL_UB_OFF;	stmt->sql_rowset_size = 1;	stmt->row_count = TDS_NO_COUNT;	stmt->row_status = NOT_IN_ROW;	/* insert into list */	stmt->next = dbc->stmt_list;	if (dbc->stmt_list)		dbc->stmt_list->prev = stmt;	dbc->stmt_list = stmt;	*phstmt = (SQLHSTMT) stmt;	if (dbc->attr.cursor_type != SQL_CURSOR_FORWARD_ONLY)		_SQLSetStmtAttr(stmt, SQL_CURSOR_TYPE, (SQLPOINTER) (TDS_INTPTR) dbc->attr.cursor_type, SQL_IS_INTEGER);	ODBC_RETURN_(dbc);}SQLRETURN ODBC_APISQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt){	tdsdump_log(TDS_DBG_FUNC, "SQLAllocStmt(%p, %p)\n", hdbc, phstmt);	return _SQLAllocStmt(hdbc, phstmt);}SQLRETURN ODBC_APISQLBindCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue){	SQLRETURN rc = SQL_SUCCESS;	TDS_DESC *ard;	struct _drecord *drec;	SQLSMALLINT orig_ard_size;	INIT_HSTMT;	tdsdump_log(TDS_DBG_FUNC, "SQLBindCol(%p, %d, %d, %p, %d, %p)\n", 			hstmt, icol, fCType, rgbValue, (int)cbValueMax, pcbValue);	/* TODO - More error checking XXX smurph */#ifdef TDS_NO_DM	/* check conversion type */	switch (fCType) {	case SQL_C_CHAR:	case SQL_C_BINARY:	case SQL_C_DEFAULT:		/* check max buffer length */		if (!IS_VALID_LEN(cbValueMax)) {			odbc_errs_add(&stmt->errs, "HY090", NULL);			rc = SQL_ERROR;		}		break;	}#endif	if (icol <= 0 || icol > 4000) {		odbc_errs_add(&stmt->errs, "07009", NULL);		rc = SQL_ERROR;	}	if (rc != SQL_SUCCESS) {		ODBC_RETURN(stmt, rc);	}	ard = stmt->ard;	orig_ard_size = ard->header.sql_desc_count;	if (icol > ard->header.sql_desc_count && desc_alloc_records(ard, icol) != SQL_SUCCESS) {		odbc_errs_add(&stmt->errs, "HY001", NULL);		ODBC_RETURN(stmt, SQL_ERROR);	}	drec = &ard->records[icol - 1];	if (odbc_set_concise_c_type(fCType, drec, 0) != SQL_SUCCESS) {		desc_alloc_records(ard, orig_ard_size);		odbc_errs_add(&stmt->errs, "HY003", NULL);		ODBC_RETURN(stmt, SQL_ERROR);	}	drec->sql_desc_octet_length = cbValueMax;	drec->sql_desc_octet_length_ptr = pcbValue;	drec->sql_desc_indicator_ptr = pcbValue;	drec->sql_desc_data_ptr = rgbValue;	/* force rebind */	stmt->row = 0;	ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLCancel(SQLHSTMT hstmt){	TDSSOCKET *tds;	/*	 * FIXME this function can be called from other thread, do not free 	 * errors for this function	 * If function is called from another thread errors are not touched	 */	/* TODO some tests required */	INIT_HSTMT;	tdsdump_log(TDS_DBG_FUNC, "SQLCancel(%p)\n", hstmt);	tds = stmt->dbc->tds_socket;	/* FIXME test current statement */	stmt->cancel_sent = 1;	if (tds_send_cancel(tds) == TDS_FAIL) {		ODBC_SAFE_ERROR(stmt);		ODBC_RETURN(stmt, SQL_ERROR);	}	if (tds_process_cancel(tds) == TDS_FAIL) {		ODBC_SAFE_ERROR(stmt);		ODBC_RETURN(stmt, SQL_ERROR);	}	/* only if we processed cancel reset statement */	if (stmt->dbc->current_statement && stmt->dbc->current_statement == stmt && tds->state == TDS_IDLE)		stmt->dbc->current_statement = NULL;	ODBC_RETURN_(stmt);}SQLRETURN ODBC_APISQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * szUID, SQLSMALLINT cbUID, SQLCHAR FAR * szAuthStr,	   SQLSMALLINT cbAuthStr){	SQLRETURN result;	TDSCONNECTION *connection;	INIT_HDBC;	tdsdump_log(TDS_DBG_FUNC, "SQLConnect(%p, %p, %d, %p, %d, %p, %d)\n", 			hdbc, szDSN, cbDSN, szUID, cbUID, szAuthStr, cbAuthStr);#ifdef TDS_NO_DM	if (szDSN && !IS_VALID_LEN(cbDSN)) {		odbc_errs_add(&dbc->errs, "HY090", "Invalid DSN buffer length");		ODBC_RETURN(dbc, SQL_ERROR);	}	if (szUID && !IS_VALID_LEN(cbUID)) {		odbc_errs_add(&dbc->errs, "HY090", "Invalid UID buffer length");		ODBC_RETURN(dbc, SQL_ERROR);	}	if (szAuthStr && !IS_VALID_LEN(cbAuthStr)) {		odbc_errs_add(&dbc->errs, "HY090", "Invalid PWD buffer length");		ODBC_RETURN(dbc, SQL_ERROR);	}#endif	connection = tds_alloc_connection(dbc->env->tds_ctx->locale);	if (!connection) {		odbc_errs_add(&dbc->errs, "HY001", NULL);		ODBC_RETURN(dbc, SQL_ERROR);	}	/* data source name */	if (szDSN || (*szDSN))		tds_dstr_copyn(&dbc->dsn, (const char *) szDSN, odbc_get_string_size(cbDSN, szDSN));	else		tds_dstr_copy(&dbc->dsn, "DEFAULT");	if (!odbc_get_dsn_info(tds_dstr_cstr(&dbc->dsn), connection)) {		tds_free_connection(connection);		odbc_errs_add(&dbc->errs, "IM007", "Error getting DSN information");		ODBC_RETURN(dbc, SQL_ERROR);	}	if (!tds_dstr_isempty(&dbc->attr.current_catalog))		tds_dstr_dup(&connection->database, &dbc->attr.current_catalog);	/*	 * username/password are never saved to ini file,	 * so you do not check in ini file	 */	/* user id */	if (szUID && (*szUID)) {		if (!tds_dstr_copyn(&connection->user_name, (char *) szUID, odbc_get_string_size(cbUID, szUID))) {			tds_free_connection(connection);			odbc_errs_add(&dbc->errs, "HY001", NULL);			ODBC_RETURN(dbc, SQL_ERROR);		}	}	/* password */	if (szAuthStr) {		if (!tds_dstr_copyn(&connection->password, (char *) szAuthStr, odbc_get_string_size(cbAuthStr, szAuthStr))) {			tds_free_connection(connection);			odbc_errs_add(&dbc->errs, "HY001", NULL);			ODBC_RETURN(dbc, SQL_ERROR);		}	}	/* DO IT */	if ((result = odbc_connect(dbc, connection)) != SQL_SUCCESS) {		tds_free_connection(connection);		ODBC_RETURN_(dbc);	}	tds_free_connection(connection);	ODBC_RETURN_(dbc);}SQLRETURN ODBC_APISQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR FAR * szColName, SQLSMALLINT cbColNameMax, SQLSMALLINT FAR * pcbColName,	       SQLSMALLINT FAR * pfSqlType, SQLULEN FAR * pcbColDef, SQLSMALLINT FAR * pibScale, SQLSMALLINT FAR * pfNullable){	TDS_DESC *ird;	struct _drecord *drec;	INIT_HSTMT;	tdsdump_log(TDS_DBG_FUNC, "SQLDescribeCol(%p, %d, %p, %d, %p, %p, %p, %p, %p)\n", 			hstmt, icol, szColName, cbColNameMax, pcbColName, pfSqlType, pcbColDef, pibScale, pfNullable);	ird = stmt->ird;	if (icol <= 0 || icol > ird->header.sql_desc_count) {		odbc_errs_add(&stmt->errs, "07009", "Column out of range");		ODBC_RETURN(stmt, SQL_ERROR);	}	/* check name length */	if (cbColNameMax < 0) {		odbc_errs_add(&stmt->errs, "HY090", NULL);		ODBC_RETURN(stmt, SQL_ERROR);	}	drec = &ird->records[icol - 1];	/* cbColNameMax can be 0 (to retrieve name length) */	if (szColName && cbColNameMax) {		SQLRETURN result;		/* straight copy column name up to cbColNameMax */		result = odbc_set_string(szColName, cbColNameMax, pcbColName, tds_dstr_cstr(&drec->sql_desc_label), -1);		if (result == SQL_SUCCESS_WITH_INFO) {			odbc_errs_add(&stmt->errs, "01004", NULL);			stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;		}	}	if (pfSqlType) {		/* TODO sure ? check documentation for date and intervals */		*pfSqlType = drec->sql_desc_concise_type;	}	if (pcbColDef) {		if (drec->sql_desc_type == SQL_NUMERIC || drec->sql_desc_type == SQL_DECIMAL) {			*pcbColDef = drec->sql_desc_precision;		} else {			*pcbColDef = drec->sql_desc_length;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -