/*
*	©Copyright 2002,2003, Microsoft Corporation
*	Microsoft Confidential.
*	Written by Sergey Vasilevskiy, 2002-2003.
*/

/*
*	Security Detail database class that uses stored procedures for individual frames.
*/

#include "stdafx.h"

using namespace TPCE;

CSecurityDetailDB::CSecurityDetailDB(CDBConnection *pDBConn)
: CTxnHarnessDBBase(pDBConn)
{	
	int i;	

	//Allocate one handle per stored procedure (frame)
	if (   SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmtFrame1) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col1) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col2) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col3) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col4) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col4Set2) != SQL_SUCCESS
		|| SQLAllocHandle(SQL_HANDLE_DESC, m_hdbc, &m_descFrame1Col5) != SQL_SUCCESS		
		)
		ThrowError(CODBCERR::eAllocHandle, SQL_HANDLE_STMT, m_hdbc);
	
	//Set statement descriptor for the parameters and the first rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col1, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	// Bound the rows fetched counter, which is the same for all the descriptors
	//
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROWS_FETCHED_PTR, &m_len, SQL_IS_POINTER);

	//Bind input/output parameters for each stored procedure

	//Frame1 input
	i = 0;
	if (   SQLBindParameter(m_hstmtFrame1, ++i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, cSYMBOL_len+1, 0, Frame1Input.symbol, cSYMBOL_len+1, NULL)!=SQL_SUCCESS
		|| SQLBindParameter(m_hstmtFrame1, ++i, SQL_PARAM_INPUT, SQL_C_TIMESTAMP, SQL_TIMESTAMP, 23, 3, &Frame1Input.start_day, 0, NULL)!=SQL_SUCCESS
		|| SQLBindParameter(m_hstmtFrame1, ++i, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_TINYINT, 0, 0, &Frame1Input.max_rows_to_return, 0, NULL)!=SQL_SUCCESS
		|| SQLBindParameter(m_hstmtFrame1, ++i, SQL_PARAM_INPUT, SQL_C_UTINYINT, SQL_TINYINT, 0, 0, (long*)&Frame1Input.access_lob_flag, 0, NULL)!=SQL_SUCCESS
		 )
		ThrowError(CODBCERR::eBindParam, SQL_HANDLE_STMT, m_hstmtFrame1);
	//Frame1 output	

	//These columns are associated with the first descriptor
	i = 0;
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.s_name, cS_NAME_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_name, cCO_NAME_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.sp_rate, cSP_RATE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ceo_name, cCEO_NAME_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_desc, cCO_DESC_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.open_date, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_st_id, cST_ID_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_line1, cAD_LINE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_line2, cAD_LINE_len+1, &m_co_ad_line2_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_town, cAD_TOWN_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_div, cAD_DIV_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_zip, cAD_ZIP_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.co_ad_cty, cAD_CTRY_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_UBIGINT, &Frame1Output.num_out, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.start_date, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.ex_date, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.pe_ratio, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.s52_wk_high, 0, &m_s53w_high_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.s52_wk_high_date, 0, &m_s53w_high_date_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.s52_wk_low, 0, &m_s53w_low_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.s52_wk_low_date, 0, &m_s53w_low_date_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.divid, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.yield, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_line1, cAD_LINE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_line2, cAD_LINE_len+1, &m_ex_ad_line2_ind) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_town, cAD_TOWN_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_div, cAD_DIV_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_zip, cAD_ZIP_len+1, NULL) != SQL_SUCCESS		
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_ad_cty, cAD_CTRY_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.ex_open, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.ex_close, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_name, cEX_NAME_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.ex_num_symb, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.ex_desc, cEX_DESC_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.last_price, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.last_open, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_IDENT, &Frame1Output.last_vol, 0, NULL) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);

	//Set statement descriptor for the second rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col2, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(Frame1Output.fin[0]), 0);	//set row-wise binding
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.fin)/sizeof(Frame1Output.fin[0])), SQL_IS_INTEGER);
	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_STATUS_PTR, StatusArray, 0);	
	

	i = 0;
	
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.fin[0].year, 0, NULL) != SQL_SUCCESS	//really short
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.fin[0].qtr, 0, NULL) != SQL_SUCCESS	//really tinyint
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.fin[0].start_date, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].rev, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].net_earn, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].basic_eps, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].dilut_eps, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].margin, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].invent, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].assets, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].liab, 0, NULL) != SQL_SUCCESS		
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].out_basic, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.fin[0].out_dilut, 0, NULL) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);

	//Set statement descriptor for the third rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col3, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(Frame1Output.day[0]), 0);	//set row-wise binding
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.day)/sizeof(Frame1Output.day[0])), SQL_IS_INTEGER);
	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_STATUS_PTR, StatusArray, 0);

	i = 0;
	
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.day[0].date, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.day[0].close, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.day[0].high, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_DOUBLE, &Frame1Output.day[0].low, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_SLONG, &Frame1Output.day[0].vol, 0, NULL) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);

	//Set statement descriptor for the forth rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col4, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(Frame1Output.news[0]), 0);	//set row-wise binding
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.news)/sizeof(Frame1Output.news[0])), SQL_IS_INTEGER);
	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_STATUS_PTR, StatusArray, 0);	

	i = 0;
	
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].item, cNI_ITEM_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.news[0].dts, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].src, cNI_SOURCE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].auth, cNI_AUTHOR_len+1, NULL) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);

	// Bind variables for non-LOB type of News data (most likely case)
	//	
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col4Set2, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(Frame1Output.news[0]), 0);	//set row-wise binding
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.news)/sizeof(Frame1Output.news[0])), SQL_IS_INTEGER);
	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_STATUS_PTR, StatusArray, 0);

	i = 0;
	
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].headline, cNI_HEADLINE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].summary, cNI_SUMMARY_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_TYPE_TIMESTAMP, &Frame1Output.news[0].dts, 0, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].src, cNI_SOURCE_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.news[0].auth, cNI_AUTHOR_len+1, &Frame1Output.news[0].auth_ind) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);


	//Set statement descriptor for the fifth rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col5, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	// Company competitor info is declared in column-wise order
	//
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);	//set column-wise binding
	SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.cp_co_name)/sizeof(Frame1Output.cp_co_name[0])), SQL_IS_INTEGER);

	i = 0;
	
	if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.cp_co_name[0], cCO_NAME_len+1, NULL) != SQL_SUCCESS
		|| SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.cp_in_name[0], cIN_NAME_len+1, NULL) != SQL_SUCCESS
		)
		ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);


	//Set statement descriptor for the sixth rowset
	//if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col6, SQL_IS_POINTER ) != SQL_SUCCESS )
	//	ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1);

	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_BIND_TYPE, (SQLPOINTER)sizeof(Frame1Output.cp_in_name[0]), 0);	//set row-wise binding
	//SQLSetStmtAttr(m_hstmtFrame1, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)(sizeof(Frame1Output.cp_in_name)/sizeof(Frame1Output.cp_in_name[0])), SQL_IS_INTEGER);	

	//i = 0;
	//
	//if (   SQLBindCol(m_hstmtFrame1, ++i, SQL_C_CHAR, &Frame1Output.cp_in_name[0], cIN_NAME_len+1, NULL) != SQL_SUCCESS		
	//	)
	//	ThrowError(CODBCERR::eBindCol, SQL_HANDLE_STMT, m_hstmtFrame1);

};

void CSecurityDetailDB::DoSecurityDetailFrame1(const TSecurityDetailFrame1Input *pFrame1Input, PSecurityDetailFrame1Output pFrame1Output)
{
	int rc;

	//Set statement descriptor for the parameters and the first rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col1, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//copy input parameters into bound locations
	Frame1Input = *pFrame1Input;		

	rc = SQLExecDirect(m_hstmtFrame1, (SQLCHAR*)"{call SecurityDetailFrame1(?, ?, ?, ?)}", SQL_NTS);
	if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
		ThrowError(CODBCERR::eExecDirect, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//Retrieve the first rowset
	if ( SQLFetch(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eFetch, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//Check indicator variables
	if (m_s53w_low_ind == SQL_NULL_DATA || m_s53w_low_date_ind == SQL_NULL_DATA)
	{
		Frame1Output.s52_wk_low = 0;
		memset(&Frame1Output.s52_wk_low_date, 0, sizeof(Frame1Output.s52_wk_low_date));
	}
	if (m_s53w_high_ind == SQL_NULL_DATA || m_s53w_high_date_ind == SQL_NULL_DATA)
	{
		Frame1Output.s52_wk_high = 0;
		memset(&Frame1Output.s52_wk_high_date, 0, sizeof(Frame1Output.s52_wk_high_date));
	}
    if (m_co_ad_line2_ind == SQL_NULL_DATA)
    {
        Frame1Output.co_ad_line2[0] = '\0';
    }
    if (m_ex_ad_line2_ind == SQL_NULL_DATA)
    {
        Frame1Output.ex_ad_line2[0] = '\0';
    }

	//move on to the second result set
	if ( SQLMoreResults(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eMoreResults, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");


	//Set statement descriptor for the second rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col2, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	if ( SQLFetch(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eFetch, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//copy the number of rows fetched
	Frame1Output.fin_len = m_len;

	// Need to find out here if there are more rows than maximum allowed.
	// Attempt to fetch more. This should normally fail with SQL_NO_DATA.
	//
	if (SQLFetch(m_hstmtFrame1) != SQL_NO_DATA)
	{	// Set to max allowed value + 1. The harness will return appropriate status code.
		//
		Frame1Output.fin_len += m_len;
	}

	//move on to the third result set
	if ( SQLMoreResults(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eMoreResults, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");


	//Set statement descriptor for the third rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col3, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	if ( SQLFetch(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eFetch, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//copy the number of rows fetched
	Frame1Output.day_len = m_len;

	// Need to find out here if there are more rows than maximum allowed.
	// Attempt to fetch more. This should normally fail with SQL_NO_DATA.
	//
	if (SQLFetch(m_hstmtFrame1) != SQL_NO_DATA)
	{	// Set to max allowed value + 1. The harness will return appropriate status code.
		//
		Frame1Output.day_len += m_len;
	}

	//move on to the forth result set
	if ( SQLMoreResults(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eMoreResults, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");


	//Set statement descriptor for the forth rowset - depending on access_LOB flag
	//
	if (pFrame1Input->access_lob_flag)
	{
		if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col4, SQL_IS_POINTER ) != SQL_SUCCESS )
			ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");
	}
	else
	{
		if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col4Set2, SQL_IS_POINTER ) != SQL_SUCCESS )
			ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");
	}

	if ( SQLFetch(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eFetch, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//copy the number of rows fetched
	Frame1Output.news_len = m_len;

	// Need to find out here if there are more rows than maximum allowed.
	// Attempt to fetch more. This should normally fail with SQL_NO_DATA.
	//
	if (SQLFetch(m_hstmtFrame1) != SQL_NO_DATA)
	{	// Set to max allowed value + 1. The harness will return appropriate status code.
		//
		Frame1Output.news_len += m_len;
	}

	//move on to the fifth result set
	if ( SQLMoreResults(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eMoreResults, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	//Set statement descriptor for the fifth rowset
	if ( SQLSetStmtAttrW( m_hstmtFrame1, SQL_ATTR_APP_ROW_DESC, m_descFrame1Col5, SQL_IS_POINTER ) != SQL_SUCCESS )
		ThrowError(CODBCERR::eSetStmtAttr, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");

	if ( SQLFetch(m_hstmtFrame1) == SQL_ERROR)
		ThrowError(CODBCERR::eFetch, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");	
	
	// Copy back the data for the harness.
	//
	pFrame1Output->last_vol = Frame1Output.last_vol;
	pFrame1Output->fin_len =  Frame1Output.fin_len;
    pFrame1Output->day_len =  Frame1Output.day_len;
	pFrame1Output->news_len = Frame1Output.news_len;
	for (int i = 0; i < sizeof(pFrame1Output->news)/sizeof(pFrame1Output->news[0]); ++i)
	{
		pFrame1Output->news[i].dts = Frame1Output.news[i].dts;
		strncpy(pFrame1Output->news[i].auth, Frame1Output.news[i].auth, sizeof(pFrame1Output->news[i].auth));
		strncpy(pFrame1Output->news[i].headline, Frame1Output.news[i].headline, sizeof(pFrame1Output->news[i].headline));
		//if (pFrame1Input->access_lob_flag)	// copy 100KBs LOBs if the flag is set
		{
			strncpy(pFrame1Output->news[i].item, Frame1Output.news[i].item, sizeof(pFrame1Output->news[i].item));
		}
		strncpy(pFrame1Output->news[i].src, Frame1Output.news[i].src, sizeof(pFrame1Output->news[i].src));
		strncpy(pFrame1Output->news[i].summary, Frame1Output.news[i].summary, sizeof(pFrame1Output->news[i].summary));
		
	}

	if ( (rc = SQLCloseCursor(m_hstmtFrame1)) != SQL_SUCCESS)
		ThrowError(CODBCERR::eCloseCursor, SQL_HANDLE_STMT, m_hstmtFrame1, "DoSecurityDetailFrame1");
};

void CSecurityDetailDB::Cleanup(void* pException)
{
	SQLCloseCursor(m_hstmtFrame1);
}
