Example #1
0
static void ARDFields_copy(const ARDFields *src, ARDFields *target)
{
	memcpy(target, src, sizeof(ARDFields));
	target->bookmark = NULL;
	if (src->bookmark)
	{
		BindInfoClass *bookmark = ARD_AllocBookmark(target);
		BindInfoClass_copy(src->bookmark, bookmark);
	}
	if (src->allocated <= 0)
	{
		target->allocated = 0;
		target->bindings = NULL;
	}
	else
	{
		int	i;

		target->bindings = malloc(target->allocated * sizeof(BindInfoClass));
		for (i = 0; i < target->allocated; i++)
			BindInfoClass_copy(&src->bindings[i], &target->bindings[i]);
	}
}
Example #2
0
/*	Associate a user-supplied buffer with a database column. */
RETCODE		SQL_API
PGAPI_BindCol(HSTMT hstmt,
			  SQLUSMALLINT icol,
			  SQLSMALLINT fCType,
			  PTR rgbValue,
			  SQLLEN cbValueMax,
			  SQLLEN FAR * pcbValue)
{
	StatementClass *stmt = (StatementClass *) hstmt;
	CSTR func = "PGAPI_BindCol";
	ARDFields	*opts;
	GetDataInfo	*gdata_info;
	BindInfoClass	*bookmark;
	RETCODE		ret = SQL_SUCCESS;

	mylog("%s: entering...\n", func);

	mylog("**** PGAPI_BindCol: stmt = %p, icol = %d\n", stmt, icol);
	mylog("**** : fCType=%d rgb=%p valusMax=%d pcb=%p\n", fCType, rgbValue, cbValueMax, pcbValue);

	if (!stmt)
	{
		SC_log_error(func, "", NULL);
		return SQL_INVALID_HANDLE;
	}

	opts = SC_get_ARDF(stmt);
	if (stmt->status == STMT_EXECUTING)
	{
		SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't bind columns while statement is still executing.", func);
		return SQL_ERROR;
	}

#define	return	DONT_CALL_RETURN_FROM_HERE ???
	SC_clear_error(stmt);
	/* If the bookmark column is being bound, then just save it */
	if (icol == 0)
	{
		bookmark = opts->bookmark;
		if (rgbValue == NULL)
		{
			if (bookmark)
			{
				bookmark->buffer = NULL;
				bookmark->used =
				bookmark->indicator = NULL;
			}
		}
		else
		{
			/* Make sure it is the bookmark data type */
			switch (fCType)
			{
				case SQL_C_BOOKMARK:
#if (ODBCVER >= 0x0300)
				case SQL_C_VARBOOKMARK:
#endif /* ODBCVER */
					break;
				default:
					SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Bind column 0 is not of type SQL_C_BOOKMARK", func);
inolog("Bind column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
					ret = SQL_ERROR;
					goto cleanup;
			}

			bookmark = ARD_AllocBookmark(opts);
			bookmark->buffer = rgbValue;
			bookmark->used =
			bookmark->indicator = pcbValue;
			bookmark->buflen = cbValueMax;
			bookmark->returntype = fCType;
		}
		goto cleanup;
	}

	/*
	 * Allocate enough bindings if not already done. Most likely,
	 * execution of a statement would have setup the necessary bindings.
	 * But some apps call BindCol before any statement is executed.
	 */
	if (icol > opts->allocated)
		extend_column_bindings(opts, icol);
	gdata_info = SC_get_GDTI(stmt);
	if (icol > gdata_info->allocated)
		extend_getdata_info(gdata_info, icol, FALSE);

	/* check to see if the bindings were allocated */
	if (!opts->bindings)
	{
		SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for bindings.", func);
		ret = SQL_ERROR;
		goto cleanup;
	}

	/* use zero based col numbers from here out */
	icol--;

	/* Reset for SQLGetData */
	gdata_info->gdata[icol].data_left = -1;

	if (rgbValue == NULL)
	{
		/* we have to unbind the column */
		opts->bindings[icol].buflen = 0;
		opts->bindings[icol].buffer = NULL;
		opts->bindings[icol].used =
		opts->bindings[icol].indicator = NULL;
		opts->bindings[icol].returntype = SQL_C_CHAR;
		opts->bindings[icol].precision = 0;
		opts->bindings[icol].scale = 0;
		if (gdata_info->gdata[icol].ttlbuf)
			free(gdata_info->gdata[icol].ttlbuf);
		gdata_info->gdata[icol].ttlbuf = NULL;
		gdata_info->gdata[icol].ttlbuflen = 0;
		gdata_info->gdata[icol].ttlbufused = 0;
	}
	else
	{
		/* ok, bind that column */
		opts->bindings[icol].buflen = cbValueMax;
		opts->bindings[icol].buffer = rgbValue;
		opts->bindings[icol].used =
		opts->bindings[icol].indicator = pcbValue;
		opts->bindings[icol].returntype = fCType;
		opts->bindings[icol].precision = 0;
#if (ODBCVER >= 0x0300)
		switch (fCType)
		{
			case SQL_C_NUMERIC:
				opts->bindings[icol].precision = 32;
				break;
			case SQL_C_TIMESTAMP:
			case SQL_C_INTERVAL_DAY_TO_SECOND:
			case SQL_C_INTERVAL_HOUR_TO_SECOND:
			case SQL_C_INTERVAL_MINUTE_TO_SECOND:
			case SQL_C_INTERVAL_SECOND:
				opts->bindings[icol].precision = 6;
				break;
		}
#endif /* ODBCVER */
		opts->bindings[icol].scale = 0;

		mylog("       bound buffer[%d] = %p\n", icol, opts->bindings[icol].buffer);
	}

cleanup:
#undef	return
	if (stmt->internal)
		ret = DiscardStatementSvp(stmt, ret, FALSE);
	return ret;
}