예제 #1
0
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;
	}
}
예제 #2
0
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);
}
예제 #3
0
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 */
}
예제 #4
0
파일: ODBCDbc.c 프로젝트: MonetDB/MonetDB
/*
 * 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);
}
예제 #5
0
파일: ODBCDbc.c 프로젝트: MonetDB/MonetDB
/*
 * 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);
}
예제 #6
0
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;
}
예제 #7
0
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);
}
예제 #8
0
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;
}
예제 #9
0
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);
}
예제 #10
0
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;
}
예제 #11
0
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);
}
예제 #12
0
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;
}
예제 #13
0
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);
	}
예제 #14
0
파일: ODBCDbc.c 프로젝트: MonetDB/MonetDB
/*
 * 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;
}
예제 #15
0
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;
}
예제 #16
0
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;
}
예제 #17
0
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;
}
예제 #18
0
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;
}