Exemplo n.º 1
0
bool CSettingsDlg::CheckDBPaths()
{
    CDBConnection dbConnection;

	try
	{
        dbConnection.Open((_bstr_t)m_strDBFrom);
        dbConnection.Close();
	}
	catch(_com_error&) 
	{
		dbConnection.Close();
        AfxMessageBox("Failed exchange db path");
		return false;
	}

	try
	{
        dbConnection.Open((_bstr_t)m_strDBTo);
        dbConnection.Close();
	}
	catch(_com_error&)
	{
		dbConnection.Close();
        AfxMessageBox("Failed ETS db path");
		return false;
	}

    return true;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------------------------------
STDMETHODIMP CEtsDivColl::Reload(void)
{
	try
	{
		CDBConnection	dbConnection;

		if(!dbConnection.IsOpened())
			dbConnection.Open(CGenegalSettings::GetDBConnectionString(), 10, 120, 300, 300);

		if (dbConnection.IsOpened())
		{
			Clear();
			CStoredProc<> db(dbConnection, L"usp_Dividends_Get");
			
			//push parameters
			db << m_nAssetID;

			CClientRecordset rs;
			rs.Open(db);

			DATE dtDividendDate;
			DOUBLE dDividendAmmount;
			for(rs.MoveFirst(); !rs.IsEOF(); ++rs) 
			{
				dtDividendDate = (vt_date)rs[L"DivYtes"];
				dDividendAmmount = rs[L"DivAmnt"];
				_CHK(AddNonUnique(dtDividendDate, dDividendAmmount), _T("Fail to Add Dividend payment date."));
			};

			dbConnection.Close();
		};
	}
	catch (_com_error& err)
	{
		TRACE_COM_ERROR(err);
	}
	catch (...)
	{
		TRACE_UNKNOWN_ERROR();
	}
	return S_OK;
}
Exemplo n.º 3
0
void *workerThread(void *data)
{
	signal(SIGTERM, signal_kill_handler);
	try {
		PThreadParameter pThrParam = reinterpret_cast<PThreadParameter>(data);

		CSocket sockDrv;
		sockDrv.setSocketFd(pThrParam->iSockfd); // client socket
#ifndef NO_DEBUG_INFO
		ostringstream msg2;
		msg2<<"workerThread "<<pThrParam->t_id<<", start, iSockfd = "<<pThrParam->iSockfd<<endl;
		pThrParam->pBrokerageHouse->logErrorMessage(msg2.str());
#endif
		PMsgDriverBrokerage pMessage = new TMsgDriverBrokerage;
		memset(pMessage, 0, sizeof(TMsgDriverBrokerage)); // zero the structure

		TMsgBrokerageDriver Reply; // return message
		INT32 iRet = 0; // transaction return code
		CDBConnection *pDBConnection = NULL;

#ifdef DB_PGSQL
		// new database connection
		pDBConnection = new CDBConnection(
				pThrParam->pBrokerageHouse->m_szHost,
				pThrParam->pBrokerageHouse->m_szDBName,
				pThrParam->pBrokerageHouse->m_szDBPort);
#else
	pDBConnection = new CDBConnection(
			pThrParam->pBrokerageHouse,
			pThrParam->pBrokerageHouse->mysql_dbname,
			pThrParam->pBrokerageHouse->mysql_host,
			pThrParam->pBrokerageHouse->mysql_user,
			pThrParam->pBrokerageHouse->mysql_pass,
			pThrParam->pBrokerageHouse->mysql_port_t,
			pThrParam->pBrokerageHouse->mysql_socket_t);
			pDBClist[pThrParam->t_id] = pDBConnection;
#ifdef CAL_RESP_TIME
			pDBConnection->init_profile_node(pThrParam->t_id, pThrParam->outputDir);
#endif
#endif


		pDBConnection->setBrokerageHouse(pThrParam->pBrokerageHouse);
		CSendToMarket sendToMarket = CSendToMarket(
				&(pThrParam->pBrokerageHouse->m_fLog));
#ifdef NO_MEE_FOR_TRADERESULT
		sendToMarket.m_pCMEE = pThrParam->pBrokerageHouse->m_pCMEE[pThrParam->t_id%pThrParam->pBrokerageHouse->iUsers];
#endif
		CMarketFeedDB marketFeedDB(pDBConnection);
		CMarketFeed marketFeed = CMarketFeed(&marketFeedDB, &sendToMarket);
		CTradeOrderDB tradeOrderDB(pDBConnection);
		CTradeOrder tradeOrder = CTradeOrder(&tradeOrderDB, &sendToMarket);

		// Initialize all classes that will be used to execute transactions.
		CBrokerVolumeDB brokerVolumeDB(pDBConnection);
		CBrokerVolume brokerVolume = CBrokerVolume(&brokerVolumeDB);
		CCustomerPositionDB customerPositionDB(pDBConnection);
		CCustomerPosition customerPosition = CCustomerPosition(&customerPositionDB);
		CMarketWatchDB marketWatchDB(pDBConnection);
		CMarketWatch marketWatch = CMarketWatch(&marketWatchDB);
		CSecurityDetailDB securityDetailDB = CSecurityDetailDB(pDBConnection);
		CSecurityDetail securityDetail = CSecurityDetail(&securityDetailDB);
		CTradeLookupDB tradeLookupDB(pDBConnection);
		CTradeLookup tradeLookup = CTradeLookup(&tradeLookupDB);
		CTradeStatusDB tradeStatusDB(pDBConnection);
		CTradeStatus tradeStatus = CTradeStatus(&tradeStatusDB);
		CTradeUpdateDB tradeUpdateDB(pDBConnection);
		CTradeUpdate tradeUpdate = CTradeUpdate(&tradeUpdateDB);
		CDataMaintenanceDB dataMaintenanceDB(pDBConnection);
		CDataMaintenance dataMaintenance = CDataMaintenance(&dataMaintenanceDB);
		CTradeCleanupDB tradeCleanupDB(pDBConnection);
		CTradeCleanup tradeCleanup = CTradeCleanup(&tradeCleanupDB);
		CTradeResultDB tradeResultDB(pDBConnection);
		CTradeResult tradeResult = CTradeResult(&tradeResultDB);

		int txn_cnt = 0;
		int abort_cnt = 0;
		double txn_time = 0;
		bool commit = true;
		double receiving_time = 0;
//		gettimeofday(&(pDBConnection->t1), NULL);
		do {
			try {
				//gettimeofday(&tt1, NULL);
				sockDrv.dbt5Receive(reinterpret_cast<void *>(pMessage),
						sizeof(TMsgDriverBrokerage));
				//gettimeofday(&tt2, NULL);
				//if(txn_cnt > 0 && difftimeval(tt2, tt1)>1)pDBConnection->outfile<<"END"<<endl;
				//pDBConnection->outfile.flush();
			} catch(CSocketErr *pErr) {
				sockDrv.dbt5Disconnect();

				ostringstream osErr;
				osErr << "Error on Receive: " << pErr->ErrorText() <<
						" at BrokerageHouse::workerThread" << endl;
				pThrParam->pBrokerageHouse->logErrorMessage(osErr.str());
				delete pErr;

				// The socket has been closed, break and let this thread die.
				break;
			}
loop:
			timeval t1, t2;
			double exec_time;
		 	gettimeofday(&t1, NULL);

			commit = true;
			iRet = CBaseTxnErr::SUCCESS;
			try {
				//  Parse Txn type
				switch (pMessage->TxnType) {

				/*case BROKER_VOLUME:
					iRet = pThrParam->pBrokerageHouse->RunBrokerVolume(
							&(pMessage->TxnInput.BrokerVolumeTxnInput),
							brokerVolume);
					break;
				case CUSTOMER_POSITION:
					iRet = pThrParam->pBrokerageHouse->RunCustomerPosition(
							&(pMessage->TxnInput.CustomerPositionTxnInput),
							customerPosition);
					break;
				case MARKET_FEED:
					iRet = pThrParam->pBrokerageHouse->RunMarketFeed(
							&(pMessage->TxnInput.MarketFeedTxnInput), marketFeed);
					break;
				case MARKET_WATCH:
					iRet = pThrParam->pBrokerageHouse->RunMarketWatch(
							&(pMessage->TxnInput.MarketWatchTxnInput), marketWatch);
					break;
				case SECURITY_DETAIL:
					iRet = pThrParam->pBrokerageHouse->RunSecurityDetail(
							&(pMessage->TxnInput.SecurityDetailTxnInput),
							securityDetail);
					break;
				case TRADE_LOOKUP:
					iRet = pThrParam->pBrokerageHouse->RunTradeLookup(
							&(pMessage->TxnInput.TradeLookupTxnInput), tradeLookup);
					break;*/
#ifdef TRADEORDER
				case TRADE_ORDER:
					iRet = pThrParam->pBrokerageHouse->RunTradeOrder(
							&(pMessage->TxnInput.TradeOrderTxnInput), tradeOrder);
					break;
#endif
#ifdef TRADEMIX
				case TRADE_ORDER:
					iRet = pThrParam->pBrokerageHouse->RunTradeOrder(
							&(pMessage->TxnInput.TradeOrderTxnInput), tradeOrder);
					break;

				case TRADE_RESULT:
					iRet = pThrParam->pBrokerageHouse->RunTradeResult(
							&(pMessage->TxnInput.TradeResultTxnInput), tradeResult);
					break;
#endif
#ifdef TRADESTATUS
				case TRADE_STATUS:
					iRet = pThrParam->pBrokerageHouse->RunTradeStatus(
							&(pMessage->TxnInput.TradeStatusTxnInput),
							tradeStatus);
					break;
#endif
#ifdef TRADEUPDATE
				case TRADE_UPDATE:
					iRet = pThrParam->pBrokerageHouse->RunTradeUpdate(
							&(pMessage->TxnInput.TradeUpdateTxnInput), tradeUpdate);
					break;
#endif
				/*case DATA_MAINTENANCE:
					iRet = pThrParam->pBrokerageHouse->RunDataMaintenance(
							&(pMessage->TxnInput.DataMaintenanceTxnInput),
							dataMaintenance);
					break;
				case TRADE_CLEANUP:
					iRet = pThrParam->pBrokerageHouse->RunTradeCleanup(
							&(pMessage->TxnInput.TradeCleanupTxnInput),
							tradeCleanup);
					break;*/
				default:
					//cout << "wrong txn type" << endl;
					iRet = ERR_TYPE_WRONGTXN;
				}
					txn_cnt++;
					pDBConnection->txn_cnt = txn_cnt;
					if(txn_cnt==1)gettimeofday(&(t_start_values[pThrParam->t_id]), NULL);
			} catch (const char *str) {

			pDBConnection->rollback();
#ifdef CAL_RESP_TIME
//			gettimeofday(&t2, NULL);
//			exec_time = difftimeval(t2, t1);
//			txn_time += exec_time;
			//pDBConnection->append_profile_node(t1, t2, pMessage->TxnType, false);
//			pDBConnection->outfile<<"error: "<<str<<endl;
//#ifdef PROFILE_EACH_QUERY
//			pDBConnection->print_profile_query();
//#endif
//			pDBConnection->outfile.flush();
#endif
				//ostringstream msg;
				//msg << time(NULL) << " " << (long long) pthread_self() << " " <<
				//		szTransactionName[pMessage->TxnType] << "; "<<str<<endl;
				//pThrParam->pBrokerageHouse->logErrorMessage(msg.str());
				iRet = CBaseTxnErr::EXPECTED_ROLLBACK;
				//cout<<"query fail:"<<str<<endl;

				commit = false;
				abort_cnt++;
				pDBConnection->abort_cnt = abort_cnt;
				//XXX:debug for trade result
			}
			gettimeofday(&t2, NULL);
			exec_time = difftimeval(t2, t1);

			txn_time += exec_time;
			pDBConnection->txn_time = txn_time;
#ifdef CAL_RESP_TIME

//			pDBConnection->append_profile_node(t1, t2, pMessage->TxnType, true);
//			pDBConnection->outfile<<commit<<" start=( "<<t1.tv_sec<<" "<<t1.tv_usec<<" ), end=( "<<t2.tv_sec<<" "<<t2.tv_usec<<" ), "<<exec_time<<", txn_cnt = "<<txn_cnt<<"total: "<<txn_time<<endl;
#ifdef PROFILE_EACH_QUERY
//			pDBConnection->print_profile_query();
#endif
//			pDBConnection->outfile.flush();

#endif
			// send status to driver
			Reply.iStatus = iRet;
			try {
				sockDrv.dbt5Send(reinterpret_cast<void *>(&Reply), sizeof(Reply));
			} catch(CSocketErr *pErr) {
				sockDrv.dbt5Disconnect();

				ostringstream osErr;
				osErr << "Error on Send: " << pErr->ErrorText() <<
						" at BrokerageHouse::workerThread" << endl;
				pThrParam->pBrokerageHouse->logErrorMessage(osErr.str());
				delete pErr;

				// The socket has been closed, break and let this thread die.
				break;
			}
		} while (true);

//		delete pDBConnection; // close connection with the database
		close(pThrParam->iSockfd); // close socket connection with the driver
		delete pThrParam;
		delete pMessage;
	} catch (CSocketErr *err) {
	}
	return NULL;
}
Exemplo n.º 4
0
void CSettingsDlg::OnSetup() 
{
    CDBConnection db;
    try 
    {
        IDataSourceLocatorPtr spLocator;

        HRESULT hr = spLocator.CreateInstance (__uuidof (DataLinks));
        if (FAILED(hr))
            utils::ThrowErrorNoSetErrorInfo(hr, L"Failed to create DataLinks object.");
      
        spLocator->hWnd = (long)m_hWnd;

        _ConnectionPtr  spConnection;
    	hr = spConnection.CreateInstance (__uuidof (Connection));
        if (FAILED(hr))
            utils::ThrowErrorNoSetErrorInfo(hr, L"Failed to create Connection object.");
    
        spConnection->ConnectionString = (LPCTSTR)m_DBConnectionStringFull;

        CComPtr<IDispatch> spDispatch = spConnection;
        if (spDispatch == 0)
            utils::ThrowErrorNoSetErrorInfo(E_NOINTERFACE, L"Failed to get IDispatch interface.");

        if (spLocator->PromptEdit(&spDispatch.p) == VARIANT_TRUE)
        {
            _ConnectionPtr  spNewConnection = spDispatch;

            if (spNewConnection == 0)
                utils::ThrowErrorNoSetErrorInfo(E_NOINTERFACE, L"Failed to get IDispatch interface.");

            CString strConnectionString = (LPCTSTR)spNewConnection->ConnectionString;
            
            try
            {
                db.Open((LPCTSTR)strConnectionString, 120, 120);
                CStoredProc<CDefaultRecordset> spVer(db, L"usp_DataInfo_Get");	
                spVer << 1;
                spVer.Open();
                spVer[L"vcKeyValue"];
                spVer.Close();
                db.Close();

                if (m_DBConnectionStringFull != strConnectionString)
                {
                    m_DBConnectionStringFull = strConnectionString;
					m_DBConnectionString = 
						    GetShortStringFromFull(spNewConnection->ConnectionString);
                    UpdateData(FALSE);
                }
            }
            catch (_com_error& e)
            {
                try
                {
                    if (db.IsOpened())
                        db.Close();
                } catch (_com_error&) { }

                CString err = _T("Invalid database. ");
                err += (LPTSTR) e.Description();
                AfxMessageBox(err);
            }
        }
    }
    catch (_com_error& e)
    {
        CString err = _T("Can't show database connection dialog.");
        err += (LPTSTR) e.Description();
        AfxMessageBox(err);
    }	
}
Exemplo n.º 5
0
HRESULT CNNTP::OnPost(IMessage * Msg, CdoEventStatus * EventStatus)
{
    HRESULT res;
    RETCODE rc;
    long global_read = 0;
    int to_inx = 0;
    SDWORD cbRet = SQL_DATA_AT_EXEC;
    if (EventStatus == NULL)
	return E_POINTER;

//    _Module.LogEvent ("Message");
    CComBSTR bStrTo, bStrBody, bStrFrom, bStrSubj, bStrCC, bStrBCC, bStrSentDate;
    CComPtr<_Stream> st;
    VARIANT sent_date;
    ::VariantInit (&sent_date);
    sent_date.vt = VT_DATE;

//    _Module.LogEvent ("After Subj");
    if (S_OK != (res = Msg->GetStream (&st)))
        return res;

//    _Module.LogEvent ("After Stream");

    CDBConnection *conn = _ppool->getConnection();
//    _Module.LogEvent ("After conn");
//    _Module.LogEvent ("From: %s, To: %s, CC: %s, BCC: %s, Subject: %s, SentOn :%s", 
//	szStrFrom, szStrTo, szStrCC, szStrBCC, szStrSubj, szStrSent);
    HSTMT hstmt = SQL_NULL_HSTMT;
    try 
    {
	int read, reconnect_count = 0;
	char szBuffer[4096];
again:
	hstmt = SQL_NULL_HSTMT;
	if (SQL_SUCCESS != SQLAllocStmt (conn->hdbc, &hstmt)) 
	    throw _T("SQLAllocStmt error");

//	SQLSetStmtOption (conn->hstmt, SQL_QUERY_TIMEOUT, 10);
	SQLSetParam (hstmt, 1, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (SQLPOINTER)2, &cbRet);
//        _Module.LogEvent ("After setparam");
	rc = SQLExecDirect (hstmt, (SQLCHAR *)"NS_POST (?)", SQL_NTS);
	if (rc != SQL_NEED_DATA && !reconnect_count)
	{
	    conn->ReportODBCError (hstmt, "Retry SQLExec error");
	    SQLFreeStmt (hstmt, SQL_DROP);
	    hstmt = SQL_NULL_HSTMT;
	    _Module.LogEvent ("Reconnecting ...");
	    reconnect_count = 1;
	    delete conn;
	    conn = new CDBConnection ();
	    goto again;
	}
	else if (rc != SQL_NEED_DATA)
	{
	    throw _T("SQLExec Error");
	}


  //      _Module.LogEvent ("After Exec");
	rc = SQLParamData (hstmt, NULL);
	if (rc != SQL_NEED_DATA)
	    throw _T("SQLParamData error");
//        _Module.LogEvent ("After ParamData");
	while (1) 
	{
	    st->ReadText (4096, &bStrBody);
	    read = wcslen (bStrBody);
	    global_read += read;
//	    _Module.LogEvent ("After ReadText");
	    if (!read)
		break;
	    ::WideCharToMultiByte (CP_ACP, 0, bStrBody, -1, szBuffer, sizeof (szBuffer), NULL, NULL);
	    rc = SQLPutData (hstmt, szBuffer, SQL_NTS);
//	    _Module.LogEvent ("After PutData");
	    if (rc != SQL_SUCCESS)
		throw _T("SQLPutData error");
	}
	rc = SQLParamData (hstmt, NULL);
//	_Module.LogEvent ("After ParamData");
	if (rc != SQL_SUCCESS)
	    throw _T("SQLParamData error");
	SQLFreeStmt (hstmt, SQL_DROP);
//	SQLFreeStmt (conn->hstmt, SQL_RESET_PARAMS);
	_Module.LogEvent ("NNTP Message (%ld chars) routed", global_read);
    }
    catch (TCHAR *ch)
    {
	conn->ReportODBCError (hstmt, ch);
	SQLFreeStmt (hstmt, SQL_DROP);
//	SQLFreeStmt (conn->hstmt, SQL_RESET_PARAMS);
	_ppool->releaseConnection(conn);
	return E_POINTER;
    }
    _ppool->releaseConnection(conn);
    return S_OK;
}
Exemplo n.º 6
0
void *workerThread(void *data)
{
	signal(SIGTERM, signal_kill_handler);

try {
		PThreadParameter pThrParam = reinterpret_cast<PThreadParameter>(data);

		CSocket sockDrv;
		sockDrv.setSocketFd(pThrParam->iSockfd); // client socket

		PMsgDriverTPCC pMessage = new TMsgDriverTPCC;
		memset(pMessage, 0, sizeof(TMsgDriverTPCC)); // zero the structure

		TMsgTPCCDriver Reply; // return message
		INT32 iRet = 0; // transaction return code
		CDBConnection *pDBConnection = NULL;

		pDBConnection = new CDBConnection(
			pThrParam->pTPCC,
			pThrParam->pTPCC->mysql_dbname,
			pThrParam->pTPCC->mysql_host,
			pThrParam->pTPCC->mysql_user,
			pThrParam->pTPCC->mysql_pass,
			pThrParam->pTPCC->mysql_port_t,
			pThrParam->pTPCC->mysql_socket_t);
#ifdef CAL_RESP_TIME
			timeval t1, t2;
			double exec_time;
			pDBClist[pThrParam->t_id] = pDBConnection;
			pDBConnection->init_profile_node(pThrParam->t_id, pThrParam->outputDir);
#endif

		CTPCCDB tpccDB(pDBConnection);

		int txn_cnt = 0;
		int abort_cnt = 0;
		double txn_time = 0;
		bool commit = true;
		double receiving_time = 0;
		do {
			try {
				sockDrv.dbt5Receive(reinterpret_cast<void *>(pMessage),
						sizeof(TMsgDriverTPCC));
			} catch(CSocketErr *pErr) {
				sockDrv.dbt5Disconnect();

				delete pErr;

				// The socket has been closed, break and let this thread die.
				break;
			}
			timeval t1, t2;
			double exec_time;
		 	gettimeofday(&t1, NULL);

			commit = true;
			iRet = CBaseTxnErr::SUCCESS;
			try {
				//  Parse Txn type
				switch (pMessage->TxnType) {
					case NEWORDER:
						iRet = pThrParam->pTPCC->RunNewOrder(&pMessage->TxnInput.neworderTxnInput, tpccDB);
						break;
					case PAYMENT:
						iRet = pThrParam->pTPCC->RunPayment(&pMessage->TxnInput.paymentTxnInput, tpccDB);
						break;
					case DELIVERY:
						iRet = pThrParam->pTPCC->RunDelivery(&pMessage->TxnInput.deliveryTxnInput, tpccDB);
						break;
					case STOCKLEVEL:
						iRet = pThrParam->pTPCC->RunStocklevel(&pMessage->TxnInput.stocklevelTxnInput, tpccDB);
						break;
					case ORDERSTATUS:
						iRet = pThrParam->pTPCC->RunOrderstatus(&pMessage->TxnInput.orderstatusTxnInput, tpccDB);
						break;
					default:
						pDBConnection->outfile<<"Wrong txn type!"<<endl;
						iRet = ERR_TYPE_WRONGTXN;
				}
				txn_cnt++;
				pDBConnection->txn_cnt = txn_cnt;
			}catch (const char *str) {
			pDBConnection->rollback();

//#ifdef CAL_RESP_TIME
//			gettimeofday(&t2, NULL);
//			exec_time = difftimeval(t2, t1);
//			txn_time += exec_time;
//#ifdef PROFILE_EACH_QUERY
//			pDBConnection->print_profile_query();
//#endif
//			pDBConnection->outfile.flush();
//#endif
				//cout<<"error: "<<str<<endl;

				iRet = CBaseTxnErr::EXPECTED_ROLLBACK;

				commit = false;
				abort_cnt++;
				pDBConnection->abort_cnt = abort_cnt;
				//XXX:debug for trade result
			}
			gettimeofday(&t2, NULL);
			exec_time = difftimeval(t2, t1);
			txn_time += exec_time;
			pDBConnection->txn_time = txn_time;
#ifdef CAL_RESP_TIME
//			pDBConnection->outfile<<commit<<" start=( "<<t1.tv_sec<<" "<<t1.tv_usec<<" ), end=( "<<t2.tv_sec<<" "<<t2.tv_usec<<" ), "<<exec_time<<", txn_cnt = "<<txn_cnt<<"total: "<<txn_time<<endl;
#ifdef PROFILE_EACH_QUERY
//			pDBConnection->print_profile_query();
#endif
			//pDBConnection->outfile<<"commit txn "<<txn_cnt<<endl;
//			pDBConnection->outfile.flush();

#endif

			// send status to driver
			Reply.iStatus = iRet;
			try {
				sockDrv.dbt5Send(reinterpret_cast<void *>(&Reply), sizeof(Reply));
			} catch(CSocketErr *pErr) {
				sockDrv.dbt5Disconnect();

				delete pErr;

				// The socket has been closed, break and let this thread die.
				break;
			}
		} while (true);

		delete pDBConnection; // close connection with the database
		close(pThrParam->iSockfd); // close socket connection with the driver
		delete pThrParam;
		delete pMessage;
	} catch (CSocketErr *err) {
	}
	return NULL;
}
Exemplo n.º 7
0
DWORD WINAPI thread_func (LPVOID param)
{
    thread_t *t = (thread_t *)param;
    char szStrTo[512];
    RETCODE rc;
    SDWORD cbRet = SQL_DATA_AT_EXEC,
	cb1 = SQL_NULL_DATA,
	cb2 = SQL_NULL_DATA,
	cb3 = SQL_NULL_DATA,
	cb4 = SQL_NULL_DATA,
	cb5 = SQL_NULL_DATA,
	cb6 = SQL_NULL_DATA,
	cb7 = SQL_NULL_DATA,
	cb8 = SQL_NULL_DATA;
    szStrTo[0] = 0;
    ::WideCharToMultiByte (CP_ACP, 0, t->bStrTo, -1, szStrTo, sizeof (szStrTo), NULL, NULL);
    CDBConnection *conn = _ppool->getConnection();
//    _Module.LogEvent ("After conn");
//    _Module.LogEvent ("From: %s, To: %s, CC: %s, BCC: %s, Subject: %s, SentOn :%s", 
//	szStrFrom, szStrTo, szStrCC, szStrBCC, szStrSubj, szStrSent);
    long ofs = 0;
    char szTo[512];
    while (-1 != (ofs = GetNextID (szStrTo, ofs, szTo)))
    {
    cb1 = SQL_NULL_DATA;
    HSTMT hstmt = SQL_NULL_HSTMT;
    try 
    {
	int reconnect_count;
again:
	reconnect_count = 0;
	hstmt = SQL_NULL_HSTMT;
	if (SQL_SUCCESS != SQLAllocStmt (conn->hdbc, &hstmt))
	    throw _T ("SQLAllocStmt error");

//	SQLSetStmtOption (hstmt, SQL_QUERY_TIMEOUT, 10);
	SQLSetParam (hstmt, 1, SQL_C_CHAR, SQL_CHAR, 0, 0, szTo, szTo[0] ? NULL : &cb1);
	SQLSetParam (hstmt, 2, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrSubj, t->bStrSubj[0] ? NULL : &cb2);
	SQLSetParam (hstmt, 3, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrCC, t->bStrCC[0] ? NULL : &cb3);
	SQLSetParam (hstmt, 4, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrBCC, t->bStrBCC[0] ? NULL : &cb4);
	SQLSetParam (hstmt, 5, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrSent, t->bStrSent[0] ? NULL : &cb5);
	SQLSetParam (hstmt, 6, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrTo, t->bStrTo[0] ? NULL : &cb6);
	SQLSetParam (hstmt, 7, SQL_C_WCHAR, SQL_CHAR, 0, 0, t->bStrFrom, t->bStrFrom[0] ? NULL : &cb7);
	SQLSetParam (hstmt, 8, SQL_C_WCHAR, SQL_LONGVARCHAR, 0, 0, t->bStrContent, t->bStrContent[0] ? NULL : &cb8);
//        _Module.LogEvent ("After setparam");
	rc = SQLExecDirect (hstmt, 
	    (SQLCHAR *)"BARE_NEW_MAIL (?, ?, ?, ?, ?, ?, ?, ?)", SQL_NTS);
	if (rc != SQL_SUCCESS && !reconnect_count)
	{
	    conn->ReportODBCError (hstmt, "Retry SQLExec error");
	    _Module.LogEvent ("Reconnecting ...");
	    reconnect_count = 1;
	    SQLFreeStmt (hstmt, SQL_DROP);
	    hstmt = SQL_NULL_HSTMT;
	    delete conn;
	    conn = new CDBConnection ();
	    goto again;
	}
	else if (rc != SQL_SUCCESS)
	{
	    throw _T("SQLExec Error");
	}


	SQLFreeStmt (hstmt, SQL_DROP);
//	SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
	_Module.LogEvent ("Message (%ld chars) from %s routed to %s", wcslen (t->bStrContent), (char *)(bstr_t)t->bStrFrom, (char *)(bstr_t)t->bStrTo);
    }
    catch (TCHAR *ch)
    {
	int deadlock = conn->ReportODBCError (hstmt, ch);
//	SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
	if (deadlock)
	    goto again;
	_ppool->releaseConnection(conn);
	delete t;
    }
    }
    _ppool->releaseConnection(conn);
    delete t;
    return 0;
}