📄 odbc3.c
字号:
/* * odbc3.c * * $Id: odbc3.c,v 1.6 2001/06/04 14:01:25 source Exp $ * * ODBC 3.x functions * * The iODBC driver manager. * * Copyright (C) 1999 by OpenLink Software <iodbc@openlinksw.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "iodbc.h"#include <sql.h>#include <sqlext.h>#if (ODBCVER >= 0x300)#include <dlproc.h>#include <herr.h>#include <henv.h>#include <hdesc.h>#include <hdbc.h>#include <hstmt.h>#include <itrace.h>RETCODE SQL_APISQLAllocHandle (SQLSMALLINT handleType, SQLHANDLE inputHandle, SQLHANDLE * outputHandlePtr){ switch (handleType) { case SQL_HANDLE_ENV: return SQLAllocEnv (outputHandlePtr); case SQL_HANDLE_DBC: { GENV (genv, inputHandle); ODBC_LOCK (); if (!IS_VALID_HENV (genv)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } CLEAR_ERRORS (genv); if (genv->odbc_ver == 0) { PUSHSQLERR (genv->herr, en_HY010); ODBC_UNLOCK (); return SQL_ERROR; } ODBC_UNLOCK (); return SQLAllocConnect (inputHandle, outputHandlePtr); } case SQL_HANDLE_STMT: return SQLAllocStmt (inputHandle, outputHandlePtr); case SQL_HANDLE_DESC: { CONN (con, inputHandle); HPROC hproc = SQL_NULL_HPROC; RETCODE retcode; DESC_t FAR *new_desc; ENTER_HDBC (con); if (((ENV_t *)(con->henv))->dodbc_ver == SQL_OV_ODBC2) { PUSHSQLERR (con->herr, en_HYC00); LEAVE_HDBC (con, SQL_ERROR); } if (!outputHandlePtr) { PUSHSQLERR (con->herr, en_HY009); LEAVE_HDBC (con, SQL_ERROR); } hproc = _iodbcdm_getproc (con, en_AllocHandle); if (hproc == SQL_NULL_HPROC) { PUSHSQLERR (con->herr, en_IM001); LEAVE_HDBC (con, SQL_ERROR); } new_desc = (DESC_t FAR *) MEM_ALLOC (sizeof (DESC_t)); memset (new_desc, 0, sizeof (DESC_t)); if (!new_desc) { PUSHSQLERR (con->herr, en_HY001); LEAVE_HDBC (con, SQL_ERROR); } CALL_DRIVER (con, con, retcode, hproc, en_AllocHandle, (handleType, con->dhdbc, &new_desc->dhdesc)); if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) { MEM_FREE (new_desc); LEAVE_HDBC (con, SQL_ERROR); } new_desc->type = SQL_HANDLE_DESC; new_desc->hdbc = con; new_desc->hstmt = NULL; new_desc->herr = NULL; new_desc->desc_cip = 0; *outputHandlePtr = new_desc; new_desc->next = con->hdesc; con->hdesc = new_desc; LEAVE_HDBC (con, SQL_SUCCESS); } default: ODBC_LOCK (); if (IS_VALID_HDBC (inputHandle)) { CONN (con, inputHandle); PUSHSQLERR (con->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; } else if (IS_VALID_HENV (inputHandle)) { GENV (genv, inputHandle); PUSHSQLERR (genv->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; } ODBC_UNLOCK (); return SQL_INVALID_HANDLE; }}/**** SQLFreeHandle ****/RETCODE SQL_APISQLFreeHandle (SQLSMALLINT handleType, SQLHANDLE handle){ switch (handleType) { case SQL_HANDLE_ENV: return SQLFreeEnv ((SQLHENV) handle); case SQL_HANDLE_DBC: return SQLFreeConnect ((SQLHDBC) handle); case SQL_HANDLE_STMT: return SQLFreeStmt ((SQLHSTMT) handle, SQL_DROP); case SQL_HANDLE_DESC: if (IS_VALID_HDESC (handle)) { DESC (pdesc, handle); CONN (pdbc, pdesc->hdbc); HPROC hproc; RETCODE retcode; DESC_t FAR *curr_desc; if (IS_VALID_HSTMT (pdesc->hstmt)) { /* the desc handle is implicit */ PUSHSQLERR (pdesc->herr, en_HY017); return SQL_ERROR; } CLEAR_ERRORS (pdesc); /* remove it from the dbc's list */ curr_desc = pdbc->hdesc; while (curr_desc) { if (curr_desc == pdesc) { pdbc->hdesc = pdesc->next; break; } if (curr_desc->next == pdesc) { curr_desc->next = pdesc->next; break; } curr_desc = curr_desc->next; } if (!curr_desc) return SQL_INVALID_HANDLE; /* and call the driver's function */ hproc = SQL_NULL_HPROC; if (pdesc->dhdesc) { /* the driver has descriptors */ hproc = _iodbcdm_getproc (pdbc, en_FreeHandle); if (hproc == SQL_NULL_HPROC) { PUSHSQLERR (pdesc->herr, en_IM001); retcode = SQL_ERROR; } else CALL_DRIVER (pdbc, pdesc, retcode, hproc, en_AllocHandle, (handleType, pdesc->dhdesc)); } _iodbcdm_freesqlerrlist (pdesc->herr); /* invalidate the handle */ pdesc->type = 0; MEM_FREE (pdesc); return retcode; } else return SQL_INVALID_HANDLE; default: ODBC_LOCK (); if (IS_VALID_HDBC (handle)) { CONN (con, handle); PUSHSQLERR (con->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; } else if (IS_VALID_HENV (handle)) { GENV (genv, handle); PUSHSQLERR (genv->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; } ODBC_UNLOCK (); return SQL_INVALID_HANDLE; }}/**** SQLSetEnvAttr ****/RETCODE SQL_APISQLSetEnvAttr (SQLHENV environmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength){ GENV (genv, environmentHandle); ODBC_LOCK (); if (!IS_VALID_HENV (genv)) { ODBC_UNLOCK (); return (SQL_INVALID_HANDLE); } CLEAR_ERRORS (genv); if (genv->hdbc) { PUSHSQLERR (genv->herr, en_HY010); ODBC_UNLOCK (); return SQL_ERROR; } switch (Attribute) { case SQL_ATTR_CONNECTION_POOLING: switch ((SQLINTEGER) ValuePtr) { case SQL_CP_OFF: case SQL_CP_ONE_PER_DRIVER: case SQL_CP_ONE_PER_HENV: ODBC_UNLOCK (); return SQL_SUCCESS; /* not implemented yet */ default: PUSHSQLERR (genv->herr, en_HY024); ODBC_UNLOCK (); return SQL_ERROR; } case SQL_ATTR_CP_MATCH: switch ((SQLINTEGER) ValuePtr) { case SQL_CP_STRICT_MATCH: case SQL_CP_RELAXED_MATCH: ODBC_UNLOCK (); return SQL_SUCCESS; /* not implemented yet */ default: PUSHSQLERR (genv->herr, en_HY024); ODBC_UNLOCK (); return SQL_ERROR; } case SQL_ATTR_ODBC_VERSION: switch ((SQLINTEGER) ValuePtr) { case SQL_OV_ODBC2: case SQL_OV_ODBC3: genv->odbc_ver = (SQLINTEGER) ValuePtr; ODBC_UNLOCK (); return (SQL_SUCCESS); default: PUSHSQLERR (genv->herr, en_HY024); ODBC_UNLOCK (); return SQL_ERROR; } case SQL_ATTR_OUTPUT_NTS: switch ((SQLINTEGER) ValuePtr) { case SQL_TRUE: ODBC_UNLOCK (); return SQL_SUCCESS; case SQL_FALSE: PUSHSQLERR (genv->herr, en_HYC00); ODBC_UNLOCK (); return SQL_ERROR; default: PUSHSQLERR (genv->herr, en_HY024); ODBC_UNLOCK (); return SQL_ERROR; } default: PUSHSQLERR (genv->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; }}RETCODE SQL_APISQLGetEnvAttr (SQLHENV environmentHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER * StringLengthPtr){ GENV (genv, environmentHandle); HDBC con; RETCODE retcode; ODBC_LOCK (); if (!IS_VALID_HENV (genv)) { ODBC_UNLOCK (); return (SQL_INVALID_HANDLE); } CLEAR_ERRORS (genv); if (Attribute != SQL_ATTR_CONNECTION_POOLING && Attribute != SQL_ATTR_CP_MATCH && Attribute != SQL_ATTR_ODBC_VERSION && Attribute != SQL_ATTR_OUTPUT_NTS) { PUSHSQLERR (genv->herr, en_HY092); ODBC_UNLOCK (); return SQL_ERROR; } /* ODBC DM env attributes */ if (Attribute == SQL_ATTR_ODBC_VERSION) { if (ValuePtr) *((SQLINTEGER *) ValuePtr) = genv->odbc_ver; ODBC_UNLOCK (); return SQL_SUCCESS; } if (Attribute == SQL_ATTR_CONNECTION_POOLING) { if (ValuePtr) *((SQLUINTEGER *) ValuePtr) = SQL_CP_OFF; ODBC_UNLOCK (); return SQL_SUCCESS; } if (Attribute == SQL_ATTR_CP_MATCH) { if (ValuePtr) *((SQLUINTEGER *) ValuePtr) = SQL_CP_STRICT_MATCH; ODBC_UNLOCK (); return SQL_SUCCESS; } if (Attribute == SQL_ATTR_OUTPUT_NTS) { if (ValuePtr) *((SQLINTEGER *) ValuePtr) = SQL_TRUE; ODBC_UNLOCK (); return SQL_SUCCESS; } /* fall back to the first driver */ if (IS_VALID_HDBC (genv->hdbc)) { CONN (con, genv->hdbc); HPROC hproc = _iodbcdm_getproc (con, en_GetEnvAttr); if (hproc != SQL_NULL_HPROC) { ENVR (env, con->henv); CALL_DRIVER (con, genv, retcode, hproc, en_GetEnvAttr, (env->dhenv, Attribute, ValuePtr, BufferLength, StringLengthPtr)); ODBC_UNLOCK (); return retcode; } else { /* possibly an ODBC2 driver */ PUSHSQLERR (genv->herr, en_IM001); ODBC_UNLOCK (); return SQL_ERROR; } } else { switch ((SQLINTEGER) Attribute) { case SQL_ATTR_CONNECTION_POOLING: if (ValuePtr) *((SQLINTEGER *) ValuePtr) = SQL_CP_OFF; break; case SQL_ATTR_CP_MATCH: if (ValuePtr) *((SQLINTEGER *) ValuePtr) = SQL_CP_STRICT_MATCH; break; case SQL_ATTR_ODBC_VERSION: if (ValuePtr) *((SQLINTEGER *) ValuePtr) = genv->odbc_ver; break; } } ODBC_UNLOCK (); return SQL_SUCCESS;}RETCODE SQL_APISQLGetStmtAttr (SQLHSTMT statementHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, UNALIGNED SQLINTEGER * StringLengthPtr){ STMT (stmt, statementHandle); HPROC hproc; RETCODE retcode; ENTER_STMT (stmt); switch (Attribute) { case SQL_ATTR_IMP_PARAM_DESC: if (ValuePtr) { if (IS_VALID_HDESC (stmt->desc[IMP_PARAM_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[IMP_PARAM_DESC]; else if (IS_VALID_HDESC (stmt->imp_desc[IMP_PARAM_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[IMP_PARAM_DESC]; else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } if (StringLengthPtr) *StringLengthPtr = SQL_IS_POINTER; LEAVE_STMT (stmt, SQL_SUCCESS); case SQL_ATTR_APP_PARAM_DESC: if (ValuePtr) { if (IS_VALID_HDESC (stmt->desc[APP_PARAM_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[APP_PARAM_DESC]; else if (IS_VALID_HDESC (stmt->imp_desc[APP_PARAM_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[APP_PARAM_DESC]; else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } if (StringLengthPtr) *StringLengthPtr = SQL_IS_POINTER; LEAVE_STMT (stmt, SQL_SUCCESS); case SQL_ATTR_IMP_ROW_DESC: if (ValuePtr) { if (IS_VALID_HDESC (stmt->desc[IMP_ROW_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[IMP_ROW_DESC]; else if (IS_VALID_HDESC (stmt->imp_desc[IMP_ROW_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[IMP_ROW_DESC]; else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } if (StringLengthPtr) *StringLengthPtr = SQL_IS_POINTER; LEAVE_STMT (stmt, SQL_SUCCESS); case SQL_ATTR_APP_ROW_DESC: if (ValuePtr) { if (IS_VALID_HDESC (stmt->desc[APP_ROW_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->desc[APP_ROW_DESC]; else if (IS_VALID_HDESC (stmt->imp_desc[APP_ROW_DESC])) *((SQLHANDLE *) ValuePtr) = (SQLHANDLE *) stmt->imp_desc[APP_ROW_DESC]; else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } if (StringLengthPtr) *StringLengthPtr = SQL_IS_POINTER; LEAVE_STMT (stmt, SQL_SUCCESS); case SQL_ATTR_ROW_ARRAY_SIZE: if (((ENV_t FAR *) ((DBC_t FAR *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) { hproc = _iodbcdm_getproc (stmt->hdbc, en_GetStmtAttr); if (hproc) { CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, en_GetStmtAttr, (stmt->dhstmt, Attribute, ValuePtr, BufferLength, StringLengthPtr)); LEAVE_STMT (stmt, retcode); } else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } else { /* an ODBC2 driver */ if (ValuePtr) *((SQLUINTEGER *) ValuePtr) = stmt->row_array_size; LEAVE_STMT (stmt, SQL_SUCCESS); } case SQL_ATTR_ENABLE_AUTO_IPD: case SQL_ATTR_CURSOR_SENSITIVITY: case SQL_ATTR_CURSOR_SCROLLABLE: case SQL_ATTR_PARAM_BIND_TYPE: case SQL_ATTR_PARAM_OPERATION_PTR: case SQL_ATTR_PARAM_STATUS_PTR: case SQL_ATTR_PARAM_BIND_OFFSET_PTR: case SQL_ATTR_ROW_BIND_OFFSET_PTR: case SQL_ATTR_ROW_OPERATION_PTR: hproc = _iodbcdm_getproc (stmt->hdbc, en_GetStmtAttr); if (!hproc) { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } else { CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, en_GetStmtAttr, (stmt->dhstmt, Attribute, ValuePtr, BufferLength, StringLengthPtr)); LEAVE_STMT (stmt, retcode); } case SQL_ATTR_FETCH_BOOKMARK_PTR: if (((ENV_t FAR *) ((DBC_t FAR *) stmt->hdbc)->henv)->dodbc_ver == SQL_OV_ODBC3) { hproc = _iodbcdm_getproc (stmt->hdbc, en_GetStmtAttr); if (hproc) { CALL_DRIVER (stmt->hdbc, stmt, retcode, hproc, en_GetStmtAttr, (stmt->dhstmt, Attribute, ValuePtr, BufferLength, StringLengthPtr)); LEAVE_STMT (stmt, retcode); } else { PUSHSQLERR (stmt->herr, en_IM001); LEAVE_STMT (stmt, SQL_ERROR); } } else { /* an ODBC2 driver */ if (ValuePtr) *((SQLPOINTER *) ValuePtr) = stmt->fetch_bookmark_ptr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -