SQLRETURN MNDBAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE *OutputHandlePtr) { switch (HandleType) { case SQL_HANDLE_ENV: if (InputHandle != NULL) return SQL_INVALID_HANDLE; return MNDBAllocEnv(OutputHandlePtr); case SQL_HANDLE_DBC: if (!isValidEnv((ODBCEnv *) InputHandle)) return SQL_INVALID_HANDLE; clearEnvErrors((ODBCEnv *) InputHandle); return MNDBAllocDbc((ODBCEnv *) InputHandle, OutputHandlePtr); case SQL_HANDLE_STMT: if (!isValidDbc((ODBCDbc *) InputHandle)) return SQL_INVALID_HANDLE; clearDbcErrors((ODBCDbc *) InputHandle); return MNDBAllocStmt((ODBCDbc *) InputHandle, OutputHandlePtr); case SQL_HANDLE_DESC: if (!isValidDbc((ODBCDbc *) InputHandle)) return SQL_INVALID_HANDLE; clearDbcErrors((ODBCDbc *) InputHandle); return MNDBAllocDesc((ODBCDbc *) InputHandle, OutputHandlePtr); default: /* we cannot set an error because we do not know the handle type of the possibly non-null handle */ return SQL_INVALID_HANDLE; } }
SQLRETURN SQL_API SQLGetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLengthPtr) { #ifdef ODBCDEBUG ODBCLOG("SQLGetConnectAttr " PTRFMT " %s " PTRFMT " %d " PTRFMT "\n", PTRFMTCAST ConnectionHandle, translateConnectAttribute(Attribute), PTRFMTCAST ValuePtr, (int) BufferLength, PTRFMTCAST StringLengthPtr); #endif if (!isValidDbc((ODBCDbc *) ConnectionHandle)) return SQL_INVALID_HANDLE; clearDbcErrors((ODBCDbc *) ConnectionHandle); return MNDBGetConnectAttr((ODBCDbc *) ConnectionHandle, Attribute, ValuePtr, BufferLength, StringLengthPtr); }
SQLRETURN MNDBFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle) { /* Check parameter handle */ if (Handle == NULL) { /* can not set an error message because the handle is NULL */ return SQL_INVALID_HANDLE; } switch (HandleType) { case SQL_HANDLE_ENV: { ODBCEnv *env = (ODBCEnv *) Handle; /* check it's validity */ if (!isValidEnv(env)) return SQL_INVALID_HANDLE; clearEnvErrors(env); return ODBCFreeEnv_(env); } case SQL_HANDLE_DBC: { ODBCDbc *dbc = (ODBCDbc *) Handle; /* check it's validity */ if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); return ODBCFreeDbc_(dbc); } case SQL_HANDLE_STMT: { ODBCStmt *stmt = (ODBCStmt *) Handle; /* check it's validity */ if (!isValidStmt(stmt)) return SQL_INVALID_HANDLE; clearStmtErrors(stmt); return ODBCFreeStmt_(stmt); } case SQL_HANDLE_DESC: { ODBCDesc *desc = (ODBCDesc *) Handle; /* check it's validity */ if (!isValidDesc(desc)) return SQL_INVALID_HANDLE; clearDescErrors(desc); return ODBCFreeDesc_(desc); } default: return SQL_INVALID_HANDLE; } /* not reached */ }
/* * Creates and adds an error msg object to the end of the error list of * this ODBCDbc struct. * When the errMsg is NULL and the SQLState is an ISO SQLState the * standard ISO message text for the SQLState is used as message. * * Precondition: dbc must be valid. SQLState and errMsg may be NULL. */ void addDbcError(ODBCDbc *dbc, const char *SQLState, const char *errMsg, int nativeErrCode) { ODBCError *error = NULL; #ifdef ODBCDEBUG ODBCLOG("addDbcError %p %s %s %d\n", dbc, SQLState, errMsg ? errMsg : getStandardSQLStateMsg(SQLState), nativeErrCode); #endif assert(isValidDbc(dbc)); error = newODBCError(SQLState, errMsg, nativeErrCode); appendODBCError(&dbc->Error, error); }
/* * Destroys the ODBCDbc object including its own managed data. * * Precondition: dbc must be valid, inactive (not connected) and * no ODBCStmt (or ODBCDesc) objects may refer to this dbc. * Postcondition: dbc is completely destroyed, dbc handle is become invalid. */ void destroyODBCDbc(ODBCDbc *dbc) { assert(isValidDbc(dbc)); assert(!dbc->Connected); assert(dbc->FirstStmt == NULL); /* first set this object to invalid */ dbc->Type = 0; /* remove this dbc from the env */ assert(dbc->Env); assert(dbc->Env->FirstDbc); { /* search for this dbc in the list */ ODBCDbc *tmp_dbc = (ODBCDbc *) dbc->Env->FirstDbc; ODBCDbc *prv_dbc = NULL; while ((tmp_dbc != NULL) && (tmp_dbc != dbc)) { prv_dbc = tmp_dbc; tmp_dbc = tmp_dbc->next; } assert(tmp_dbc == dbc); /* we must have found it */ /* now remove it from the linked list */ if (prv_dbc != NULL) { prv_dbc->next = dbc->next; } else { dbc->Env->FirstDbc = dbc->next; } } /* cleanup own managed data */ deleteODBCErrorList(&dbc->Error); if (dbc->dsn) free(dbc->dsn); if (dbc->uid) free(dbc->uid); if (dbc->pwd) free(dbc->pwd); if (dbc->host) free(dbc->host); if (dbc->dbname) free(dbc->dbname); free(dbc); }
SQLRETURN SQL_API SQLSetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; SQLPOINTER ptr; SQLINTEGER n; SQLRETURN rc; #ifdef ODBCDEBUG ODBCLOG("SQLSetConnectAttrW " PTRFMT " %s " PTRFMT " %d\n", PTRFMTCAST ConnectionHandle, translateConnectAttribute(Attribute), PTRFMTCAST ValuePtr, (int) StringLength); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); switch (Attribute) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: if (StringLength > 0) /* convert from bytes to characters */ StringLength /= 2; fixWcharIn(ValuePtr, StringLength, SQLCHAR, ptr, addDbcError, dbc, return SQL_ERROR); n = SQL_NTS; break; default: ptr = ValuePtr; n = StringLength; break; } rc = MNDBSetConnectAttr(dbc, Attribute, ptr, n); if (ptr && ptr != ValuePtr) free(ptr); return rc; }
SQLRETURN SQL_API SQLSetConnectOption(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN ValuePtr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; #ifdef ODBCDEBUG ODBCLOG("SQLSetConnectOption " PTRFMT " %s " ULENFMT "\n", PTRFMTCAST ConnectionHandle, translateConnectOption(Option), ULENCAST ValuePtr); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); return MNDBSetConnectOption(dbc, Option, ValuePtr); }
SQLRETURN SQL_API SQLSetConnectOptionW(SQLHDBC ConnectionHandle, SQLUSMALLINT Option, SQLULEN ValuePtr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; SQLPOINTER ptr = (SQLPOINTER) (uintptr_t) ValuePtr; SQLULEN p; SQLRETURN rc; #ifdef ODBCDEBUG ODBCLOG("SQLSetConnectOptionW " PTRFMT " %s " ULENFMT "\n", PTRFMTCAST ConnectionHandle, translateConnectOption(Option), ULENCAST ValuePtr); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); switch (Option) { case SQL_ATTR_CURRENT_CATALOG: case SQL_ATTR_TRACEFILE: case SQL_ATTR_TRANSLATE_LIB: fixWcharIn((SQLPOINTER) (uintptr_t) ValuePtr, SQL_NTS, SQLCHAR, ptr, addDbcError, dbc, return SQL_ERROR); p = (SQLULEN) (uintptr_t) ptr; break; default: p = ValuePtr; break; } rc = MNDBSetConnectOption(dbc, Option, p); if (ptr &&p != ValuePtr) free(ptr); return rc; }
SQLRETURN SQL_API SQLBrowseConnect(SQLHDBC ConnectionHandle, SQLCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2Ptr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; #ifdef ODBCDEBUG ODBCLOG("SQLBrowseConnect " PTRFMT, PTRFMTCAST ConnectionHandle); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); return MNDBBrowseConnect(dbc, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr); }
SQLRETURN SQL_API SQLBrowseConnectW(SQLHDBC ConnectionHandle, SQLWCHAR *InConnectionString, SQLSMALLINT StringLength1, SQLWCHAR *OutConnectionString, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength2Ptr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; SQLCHAR *in = NULL, *out; SQLSMALLINT n; SQLRETURN rc; #ifdef ODBCDEBUG ODBCLOG("SQLBrowseConnectW " PTRFMT, PTRFMTCAST ConnectionHandle); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); fixWcharIn(InConnectionString, StringLength1, SQLCHAR, in, addDbcError, dbc, return SQL_ERROR); out = malloc(1024); if (out == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return SQL_ERROR; } rc = MNDBBrowseConnect(dbc, in, SQL_NTS, out, 1024, &n); if (SQL_SUCCEEDED(rc) || rc == SQL_NEED_DATA) { fixWcharOut(rc, out, n, OutConnectionString, BufferLength, StringLength2Ptr, 1, addDbcError, dbc); } free(out); if (in) free(in); return rc; }
SQLRETURN SQL_API SQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength) { #ifdef ODBCDEBUG ODBCLOG("SQLSetConnectAttr %p %s %p %d\n", ConnectionHandle, translateConnectAttribute(Attribute), ValuePtr, (int) StringLength); #endif if (!isValidDbc((ODBCDbc *) ConnectionHandle)) return SQL_INVALID_HANDLE; clearDbcErrors((ODBCDbc *) ConnectionHandle); return MNDBSetConnectAttr((ODBCDbc *) ConnectionHandle, Attribute, ValuePtr, StringLength); }
SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; #ifdef ODBCDEBUG ODBCLOG("SQLDisconnect " PTRFMT "\n", PTRFMTCAST ConnectionHandle); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); /* check connection state, should be connected */ if (!dbc->Connected) { /* Connection does not exist */ addDbcError(dbc, "08003", NULL, 0); return SQL_ERROR; } while (dbc->FirstStmt != NULL) if (ODBCFreeStmt_(dbc->FirstStmt) == SQL_ERROR) return SQL_ERROR; /* client waves goodbye */ mapi_disconnect(dbc->mid); mapi_destroy(dbc->mid); dbc->mid = NULL; dbc->cachelimit = 0; dbc->Mdebug = 0; dbc->Connected = 0; return SQL_SUCCESS; }
SQLRETURN SQL_API SQLGetFunctions(SQLHDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *SupportedPtr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; #ifdef ODBCDEBUG ODBCLOG("SQLGetFunctions " PTRFMT " %s\n", PTRFMTCAST ConnectionHandle, translateFunctionId(FunctionId)); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); if (!SQL_FUNC_EXISTS(FuncExistMap, FuncImplemented[0])) { /* not yet initialized, so do it now */ UWORD *p; for (p = FuncImplemented; p < &FuncImplemented[NFUNCIMPLEMENTED]; p++) FuncExistMap[*p >> 4] |= 1 << (*p & 0xF); }
/* * Extracts an error object from the error list of this ODBCDbc struct. * The error object itself is removed from the error list. * The caller is now responsible for freeing the error object memory. * * Precondition: dbc and error must be valid * Postcondition: returns a ODBCError object or null when no error is available. */ ODBCError * getDbcError(ODBCDbc *dbc) { assert(isValidDbc(dbc)); return dbc->Error; }
static SQLRETURN MNDBGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, SQLPOINTER DiagInfoPtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr) { ODBCError *err; ODBCDbc *dbc = NULL; /* input & output parameters validity checks */ switch (HandleType) { case SQL_HANDLE_ENV: /* Check if this struct is still valid/alive */ if (!isValidEnv((ODBCEnv *) Handle)) return SQL_INVALID_HANDLE; err = ((ODBCEnv *) Handle)->Error; break; case SQL_HANDLE_DBC: /* Check if this struct is still valid/alive */ dbc = (ODBCDbc *) Handle; if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; err = dbc->Error; break; case SQL_HANDLE_STMT: /* Check if this struct is still valid/alive */ if (!isValidStmt((ODBCStmt *) Handle)) return SQL_INVALID_HANDLE; err = ((ODBCStmt *) Handle)->Error; dbc = ((ODBCStmt *) Handle)->Dbc; break; case SQL_HANDLE_DESC: /* Check if this struct is still valid/alive */ if (!isValidDesc((ODBCDesc *) Handle)) return SQL_INVALID_HANDLE; err = ((ODBCDesc *) Handle)->Error; dbc = ((ODBCDesc *) Handle)->Dbc; break; default: return SQL_INVALID_HANDLE; } /* header fields */ switch (DiagIdentifier) { case SQL_DIAG_CURSOR_ROW_COUNT: /* SQLLEN */ if (HandleType != SQL_HANDLE_STMT) return SQL_ERROR; *(SQLLEN *) DiagInfoPtr = (SQLLEN) ((ODBCStmt *) Handle)->rowSetSize; return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION: /* SQLCHAR* */ if (HandleType != SQL_HANDLE_STMT) return SQL_ERROR; copyDiagString("", DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; case SQL_DIAG_DYNAMIC_FUNCTION_CODE: /* SQLINTEGER */ if (HandleType != SQL_HANDLE_STMT) return SQL_ERROR; *(SQLINTEGER *) DiagInfoPtr = SQL_DIAG_UNKNOWN_STATEMENT; return SQL_SUCCESS; case SQL_DIAG_NUMBER: /* SQLINTEGER */ *(SQLINTEGER *) DiagInfoPtr = getErrorRecCount(err); return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: /* SQLRETURN */ *(SQLRETURN *) DiagInfoPtr = SQL_SUCCESS; return SQL_SUCCESS; case SQL_DIAG_ROW_COUNT: /* SQLLEN */ if (HandleType != SQL_HANDLE_STMT || ((ODBCStmt *) Handle)->State < EXECUTED0) return SQL_ERROR; *(SQLLEN *) DiagInfoPtr = (SQLLEN) ((ODBCStmt *) Handle)->rowcount; return SQL_SUCCESS; } /* record fields */ if (RecNumber <= 0) return SQL_ERROR; err = getErrorRec(err, RecNumber); if (err == NULL) return SQL_NO_DATA; switch (DiagIdentifier) { case SQL_DIAG_CLASS_ORIGIN:{ /* SQLCHAR* */ char *msg = strncmp(getSqlState(err), "IM", 2) == 0 ? "ODBC 3.0" : "ISO 9075"; copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } case SQL_DIAG_COLUMN_NUMBER: /* SQLINTEGER */ if (HandleType != SQL_HANDLE_STMT) return SQL_ERROR; *(SQLINTEGER *) DiagInfoPtr = SQL_COLUMN_NUMBER_UNKNOWN; return SQL_SUCCESS; case SQL_DIAG_CONNECTION_NAME:{ /* SQLCHAR* */ char *msg = "MonetDB ODBC/Mapi"; copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } #if 0 /* not clear yet what to return here */ case SQL_DIAG_MESSAGE_TEXT: { /* SQLCHAR* */ char msg[1024]; snprintf(msg, sizeof(msg), ""); copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } #endif case SQL_DIAG_NATIVE: /* SQLINTEGER */ *(SQLINTEGER *) DiagInfoPtr = getNativeErrorCode(err); return SQL_SUCCESS; case SQL_DIAG_ROW_NUMBER: /* SQLLEN */ if (HandleType != SQL_HANDLE_STMT) return SQL_ERROR; *(SQLLEN *) DiagInfoPtr = SQL_ROW_NUMBER_UNKNOWN; return SQL_SUCCESS; case SQL_DIAG_SERVER_NAME:{ /* SQLCHAR* */ char *msg = dbc && dbc->Connected && dbc->dsn ? dbc->dsn : ""; copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } case SQL_DIAG_SQLSTATE:{ /* SQLCHAR* */ char *msg = getSqlState(err); copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } case SQL_DIAG_SUBCLASS_ORIGIN:{ /* SQLCHAR* */ char *state = getSqlState(err); char *msg; if (('0' <= state[0] && state[0] <= '4') || ('A' <= state[0] && state[0] <= 'H')) msg = "ISO 9075"; /* defined by standard */ else msg = "ODBC 3.0"; /* effectively just "IM" */ copyDiagString(msg, DiagInfoPtr, BufferLength, StringLengthPtr); return SQL_SUCCESS; } } /* Currently no Diagnostic Fields are supported. Hence we always return NO_DATA */ return SQL_NO_DATA; }
SQLRETURN SQL_API SQLGetConnectAttrW(SQLHDBC ConnectionHandle, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER BufferLength, SQLINTEGER *StringLengthPtr) { ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle; SQLRETURN rc; SQLPOINTER ptr; SQLINTEGER n; #ifdef ODBCDEBUG ODBCLOG("SQLGetConnectAttrW " PTRFMT " %s " PTRFMT " %d " PTRFMT "\n", PTRFMTCAST ConnectionHandle, translateConnectAttribute(Attribute), PTRFMTCAST ValuePtr, (int) BufferLength, PTRFMTCAST StringLengthPtr); #endif if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); switch (Attribute) { /* all string attributes */ case SQL_ATTR_CURRENT_CATALOG: ptr = malloc(BufferLength); if (ptr == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return SQL_ERROR; } break; default: ptr = ValuePtr; break; } rc = MNDBGetConnectAttr(dbc, Attribute, ptr, BufferLength, &n); if (ptr != ValuePtr) { if (rc == SQL_SUCCESS_WITH_INFO) { clearDbcErrors(dbc); free(ptr); ptr = malloc(++n); /* add one for NULL byte */ if (ptr == NULL) { /* Memory allocation error */ addDbcError(dbc, "HY001", NULL, 0); return SQL_ERROR; } rc = MNDBGetConnectAttr(dbc, Attribute, ptr, n, &n); } if (SQL_SUCCEEDED(rc)) { SQLSMALLINT nn = (SQLSMALLINT) n; fixWcharOut(rc, ptr, nn, ValuePtr, BufferLength, StringLengthPtr, 2, addDbcError, dbc); } free(ptr); } else if (StringLengthPtr) *StringLengthPtr = n; return rc; }
SQLRETURN MNDBGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *SQLState, SQLINTEGER *NativeErrorPtr, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLengthPtr) { ODBCError *err; SQLRETURN retCode; char *msg; SQLSMALLINT msgLen; switch (HandleType) { case SQL_HANDLE_ENV: /* Check if this struct is still valid/alive */ if (!isValidEnv((ODBCEnv *) Handle)) return SQL_INVALID_HANDLE; err = getEnvError((ODBCEnv *) Handle); break; case SQL_HANDLE_DBC: /* Check if this struct is still valid/alive */ if (!isValidDbc((ODBCDbc *) Handle)) return SQL_INVALID_HANDLE; err = getDbcError((ODBCDbc *) Handle); break; case SQL_HANDLE_STMT: /* Check if this struct is still valid/alive */ if (!isValidStmt((ODBCStmt *) Handle)) return SQL_INVALID_HANDLE; err = getStmtError((ODBCStmt *) Handle); break; case SQL_HANDLE_DESC: /* not yet supported */ return Handle ? SQL_NO_DATA : SQL_INVALID_HANDLE; default: return SQL_INVALID_HANDLE; } /* Note: BufferLength may be 0 !! */ if (BufferLength < 0) return SQL_ERROR; if (RecNumber <= 0) return SQL_ERROR; err = getErrorRec(err, RecNumber); /* Check the error object from the handle, it may be NULL when * no (more) errors are available */ if (err == NULL) return SQL_NO_DATA; /* Now fill the output parameters where possible */ if (SQLState) { char *state = getSqlState(err); assert(state); /* copy only the first SQL_SQLSTATE_SIZE (5) chars in * the buffer and make it null terminated */ strncpy((char *) SQLState, state, SQL_SQLSTATE_SIZE); SQLState[SQL_SQLSTATE_SIZE] = 0; } if (NativeErrorPtr) *NativeErrorPtr = getNativeErrorCode(err); msg = getMessage(err); msgLen = msg ? (SQLSMALLINT) strlen(msg) : 0; retCode = SQL_SUCCESS; if (MessageText && BufferLength > 0) { BufferLength--; /* reserve space for term NULL byte */ MessageText[BufferLength] = 0; /* write it already */ /* first write the error message prefix text: * [MonetDB][ODBC driver VERSION]; this is * required by the ODBC spec and used to * determine where the error originated */ if (BufferLength > 0) strncpy((char *) MessageText, ODBCErrorMsgPrefix, BufferLength); BufferLength -= ODBCErrorMsgPrefixLength; MessageText += ODBCErrorMsgPrefixLength; /* next append the error msg itself */ if (msg && BufferLength > 0) { strncpy((char *) MessageText, msg, BufferLength); BufferLength -= msgLen; } if (BufferLength < 0) { /* it didn't fit */ retCode = SQL_SUCCESS_WITH_INFO; } } else { /* There is no valid MessageText buffer or its * buffer size is 0. In these cases we cannot * write the prefix and message. We just set * the return code. */ retCode = SQL_SUCCESS_WITH_INFO; } if (TextLengthPtr) *TextLengthPtr = (SQLSMALLINT) (msgLen + ODBCErrorMsgPrefixLength); return retCode; }
SQLRETURN MNDBEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT CompletionType) { ODBCEnv *env = NULL; ODBCDbc *dbc = NULL; SQLHANDLE StatementHandle; RETCODE rc; /* check parameters HandleType and Handle for validity */ switch (HandleType) { case SQL_HANDLE_DBC: dbc = (ODBCDbc *) Handle; if (!isValidDbc(dbc)) return SQL_INVALID_HANDLE; clearDbcErrors(dbc); if (!dbc->Connected) { /* Connection does not exist */ addDbcError(dbc, "08003", NULL, 0); return SQL_ERROR; } break; case SQL_HANDLE_ENV: env = (ODBCEnv *) Handle; if (!isValidEnv(env)) return SQL_INVALID_HANDLE; clearEnvErrors(env); if (env->sql_attr_odbc_version == 0) { /* Function sequence error */ addEnvError(env, "HY010", NULL, 0); return SQL_ERROR; } break; case SQL_HANDLE_STMT: if (isValidStmt((ODBCStmt *) Handle)) { clearStmtErrors((ODBCStmt *) Handle); /* Invalid attribute/option identifier */ addStmtError((ODBCStmt *) Handle, "HY092", NULL, 0); return SQL_ERROR; } return SQL_INVALID_HANDLE; case SQL_HANDLE_DESC: if (isValidDesc((ODBCDesc *) Handle)) { clearDescErrors((ODBCDesc *) Handle); /* Invalid attribute/option identifier */ addDescError((ODBCDesc *) Handle, "HY092", NULL, 0); return SQL_ERROR; } return SQL_INVALID_HANDLE; default: return SQL_INVALID_HANDLE; } /* check parameter CompletionType */ if (CompletionType != SQL_COMMIT && CompletionType != SQL_ROLLBACK) { /* Invalid transaction operation code */ if (HandleType == SQL_HANDLE_DBC) addDbcError(dbc, "HY012", NULL, 0); else addEnvError(env, "HY012", NULL, 0); return SQL_ERROR; } if (HandleType == SQL_HANDLE_ENV) { RETCODE rc1 = SQL_SUCCESS; for (dbc = env->FirstDbc; dbc; dbc = dbc->next) { assert(isValidDbc(dbc)); if (!dbc->Connected) continue; rc = MNDBEndTran(SQL_HANDLE_DBC, dbc, CompletionType); if (rc == SQL_ERROR) rc1 = SQL_ERROR; else if (rc == SQL_SUCCESS_WITH_INFO && rc1 != SQL_ERROR) rc1 = rc; } return rc1; } assert(HandleType == SQL_HANDLE_DBC); if (dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON) { /* nothing to do if in autocommit mode */ return SQL_SUCCESS; } /* construct a statement object and excute a SQL COMMIT or ROLLBACK */ rc = MNDBAllocStmt(dbc, &StatementHandle); if (SQL_SUCCEEDED(rc)) { ODBCStmt *stmt = (ODBCStmt *) StatementHandle; rc = MNDBExecDirect(stmt, CompletionType == SQL_COMMIT ? (SQLCHAR *) "commit" : (SQLCHAR *) "rollback", SQL_NTS); if (rc == SQL_ERROR || rc == SQL_SUCCESS_WITH_INFO) { /* get the error/warning and post in on the * dbc handle */ SQLCHAR sqlState[SQL_SQLSTATE_SIZE + 1]; SQLINTEGER nativeErrCode; SQLCHAR msgText[SQL_MAX_MESSAGE_LENGTH + 1]; (void) MNDBGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlState, &nativeErrCode, msgText, sizeof(msgText), NULL); addDbcError(dbc, (char *) sqlState, (char *) msgText + ODBCErrorMsgPrefixLength, nativeErrCode); } /* clean up the statement handle */ ODBCResetStmt(stmt); ODBCFreeStmt_(stmt); for (stmt = dbc->FirstStmt; stmt; stmt = stmt->next) ODBCResetStmt(stmt); } else { /* could not allocate a statement object */ /* Memory management error */ addDbcError(dbc, "HY013", NULL, 0); return SQL_ERROR; } return rc; }