SQLRETURN SQL_API SQLDataSourcesW(SQLHENV EnvironmentHandle, SQLUSMALLINT Direction, SQLWCHAR *ServerName, SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLWCHAR *Description, SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2) { ODBCEnv *env = (ODBCEnv *) EnvironmentHandle; SQLRETURN rc; SQLCHAR *server, *descr; SQLSMALLINT length1, length2; #ifdef ODBCDEBUG ODBCLOG("SQLDataSourcesW " PTRFMT " %s\n", PTRFMTCAST EnvironmentHandle, translateDirection(Direction)); #endif if (!isValidEnv(env)) return SQL_INVALID_HANDLE; clearEnvErrors(env); server = malloc(100); descr = malloc(100); if (server == NULL || descr == NULL) { /* Memory allocation error */ addEnvError(env, "HY001", NULL, 0); if (server) free(server); if (descr) free(descr); return SQL_ERROR; } rc = MNDBDataSources(env, Direction, server, 100, &length1, descr, 100, &length2); if (SQL_SUCCEEDED(rc)) { fixWcharOut(rc, server, length1, ServerName, BufferLength1, NameLength1, 1, addEnvError, env); fixWcharOut(rc, descr, length2, Description, BufferLength2, NameLength2, 1, addEnvError, env); } free(server); free(descr); 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; }
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; }