void ODBCAppender::ODBCAppenderPriv::setPreparedStatement()

in src/main/cpp/odbcappender.cpp [395:499]


void ODBCAppender::ODBCAppenderPriv::setPreparedStatement(SQLHDBC con, Pool& p)
{
	auto ret = SQLAllocHandle( SQL_HANDLE_STMT, con, &this->preparedStatement);
	if (ret < 0)
	{
		throw SQLException( SQL_HANDLE_DBC, con, "Failed to allocate statement handle.", p);
	}

#if LOG4CXX_LOGCHAR_IS_WCHAR
	ret = SQLPrepareW(this->preparedStatement, (SQLWCHAR*)this->sqlStatement.c_str(), SQL_NTS);
#elif LOG4CXX_LOGCHAR_IS_UTF8
	ret = SQLPrepareA(this->preparedStatement, (SQLCHAR*)this->sqlStatement.c_str(), SQL_NTS);
#else
	SQLWCHAR* wsql;
	encode(&wsql, this->sqlStatement, p);
	ret = SQLPrepareW(this->preparedStatement, wsql, SQL_NTS);
#endif
	if (ret < 0)
	{
		throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to prepare sql statement.", p);
	}

	int parameterNumber = 0;
	for (auto& item : this->parameterValue)
	{
		++parameterNumber;
		SQLSMALLINT  targetType;
		SQLULEN      targetMaxCharCount;
		SQLSMALLINT  decimalDigits;
		SQLSMALLINT  nullable;
		auto ret = SQLDescribeParam
			( this->preparedStatement
			, parameterNumber
			, &targetType
			, &targetMaxCharCount
			, &decimalDigits
			, &nullable
			);
		if (ret < 0)
		{
			throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to describe parameter", p);
		}
		if (SQL_CHAR == targetType || SQL_VARCHAR == targetType || SQL_LONGVARCHAR == targetType)
		{
			item.paramType = SQL_C_CHAR;
			item.paramMaxCharCount = targetMaxCharCount;
			item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(char) + sizeof(char);
			item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(char));
		}
		else if (SQL_WCHAR == targetType || SQL_WVARCHAR == targetType || SQL_WLONGVARCHAR == targetType)
		{
			item.paramType = SQL_C_WCHAR;
			item.paramMaxCharCount = targetMaxCharCount;
			item.paramValueSize = (SQLINTEGER)(targetMaxCharCount) * sizeof(wchar_t) + sizeof(wchar_t);
			item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(wchar_t));
		}
		else if (SQL_TYPE_TIMESTAMP == targetType || SQL_TYPE_DATE == targetType || SQL_TYPE_TIME == targetType
			|| SQL_DATETIME == targetType)
		{
			item.paramType = SQL_C_TYPE_TIMESTAMP;
			item.paramMaxCharCount = (0 <= decimalDigits) ? decimalDigits : 6;
			item.paramValueSize = sizeof(SQL_TIMESTAMP_STRUCT);
			item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize);
		}
		else
		{
			if (SQL_INTEGER != targetType)
			{
				LogString msg(LOG4CXX_STR("Unexpected targetType ("));
				helpers::StringHelper::toString(targetType, p, msg);
				msg += LOG4CXX_STR(") at parameter ");
				helpers::StringHelper::toString(parameterNumber, p, msg);
				msg += LOG4CXX_STR(" while preparing SQL");
				LogLog::warn(msg);
			}
			item.paramMaxCharCount = 30;
#if LOG4CXX_LOGCHAR_IS_UTF8
			item.paramType = SQL_C_CHAR;
			item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(char);
			item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(char));
#else
			item.paramType = SQL_C_WCHAR;
			item.paramValueSize = (SQLINTEGER)(item.paramMaxCharCount) * sizeof(wchar_t);
			item.paramValue = (SQLPOINTER)p.palloc(item.paramValueSize + sizeof(wchar_t));
#endif
		}
		item.strLen_or_Ind = SQL_NTS;
		ret = SQLBindParameter
			( this->preparedStatement
			, parameterNumber
			, SQL_PARAM_INPUT
			, item.paramType  // ValueType
			, targetType
			, targetMaxCharCount
			, decimalDigits
			, item.paramValue
			, item.paramValueSize
			, &item.strLen_or_Ind
			);
		if (ret < 0)
		{
			throw SQLException(SQL_HANDLE_STMT, this->preparedStatement, "Failed to bind parameter", p);
		}
	}
}