void UBTAuditLogEx(const char *szFile, const char *pzText, bool bNewLine, bool push) { if (g_pchLogFile == LOGGING_UNASSIGNED) { try { g_pchLogFile = (char *)GetProfile().GetString("Debug", "DebugTraceXML",false); if (g_pchLogFile && g_pchLogFile[0]) { // g_pchLogFile is valid and logging is turned ON } else { // Turn off logging and don't check the environment variable anymore (it's slow) g_pchLogFile = (char *)LOGGING_OFF; } } catch (GException &) { } } if (g_pchLogFile != LOGGING_OFF) { // trace out the xml being sent to the server // fstream fsOut(g_pchLogFile, ios::out | ios::app); GString strOut; for (int i = 0; i < nIndent; i++) strOut << " "; strOut << '(' << szFile << ')'; if (push) strOut << " push: "; else strOut << " pop : "; if (pzText) strOut << pzText; else strOut << "(null)"; if (bNewLine) strOut << "\n"; strOut.ToFileAppend(g_pchLogFile); } }
const char *XMLProcedureCall::Execute( XMLObject *pDestinatonObject /*= 0*/, bool bDestinationObjectTagPresent /* = 1*/) { if (!m_DataSource) { throw GException("XMLProcedureCall", 8); } if (!m_strSchema.IsEmpty()) AddAttribute( "Schema", (const char *)m_strSchema ); m_DataSource->AddAttributes(this); if ( m_lstProcedures.Size() > 1 || // Multiple DB operations or joins(within the same transaction) m_bForceTransaction || // Force Transactional strstr((const char *)m_strProcedureName,"::") ) // executing CustomDLL.procedure { AddAttribute( "Transaction", "yes" ); } if ( GetRowCount() != (long)-1 ) { AddAttribute( "maxObjects", GetRowCount() ); } if (m_pzReportTemplateName) { AddAttribute( "MergeXML", "yes" ); AddAttribute( "Template", m_pzReportTemplateName ); } ToXML(&m_strRequest); if (m_lpfnSend) { m_lpfnSend((const char *)m_strRequest); } const char *pDebugFile = GetProfile().GetString("Debug", "DebugTraceXML", false); if (pDebugFile && pDebugFile[0]) { // trace out the xml being sent to the server GString strTrace; strTrace.Format("\n\n\n\nSent To [%s]-----------\n%s",m_DataSource->GetServerAddress(),(const char *)m_strRequest); strTrace.ToFileAppend(pDebugFile); } int nRetryCount = 0; RESEND: try { m_strXml = m_DataSource->send( (const char *)m_strProcedureName, (const char *)m_strRequest, (int)m_strRequest.Length(),/* Length w/o Null terminator */ 0, &m_pUserData,"TransactXML="); if (m_lpfnRecv) m_lpfnRecv(m_strXml); } catch(GException &e) { // "General error parsing XML stream" means the data was corrupted in transit. if (e.GetError() == 7) { // Resend the request. if (nRetryCount++ < 3) { TRACE_WARNING("Attempting resend" ); goto RESEND; } } // "the handle is invalid". We need to 'reboot' the datasource. (WININET) if ((e.GetError() == 6) && (e.GetSystem() == 0)) { // Resend the request. if (nRetryCount++ < 3) { TRACE_WARNING("Attempting resend" ); m_DataSource->IPAddressChange(); goto RESEND; } } // This helps distinguish Client errors from Server errors // unless the error was a client side connect error. throw GException("XMLProcedureCall", 4, m_DataSource->GetServerAddress(), e.GetDescription()); } if (pDebugFile && pDebugFile[0]) { // trace out the xml returned from the server GString strTrace("\n\n\n\nReceived:\n----------\n"); const char *pXML = GetXML(); if (pXML) strTrace += pXML; strTrace.ToFileAppend(pDebugFile); } // map to tags that we expect to recieve in the query results LoadMemberMappings(); if ( m_bRunObjectFactory && m_strXml && m_strXml[0] ) { const char *pFactoryXML = m_strXml; if (m_pzReportTemplateName) { pFactoryXML = GetXML(); } try { if (pDestinatonObject) { // The tag "XMLQueryResults" can be anything. The outer most // tag is never verified, this object will contain the Root // starting point for factorization (the pDestinatonObject object) if (bDestinationObjectTagPresent) { XMLRelationshipWrapper objectContainer("XMLQueryResults"); objectContainer.ModifyObjectBehavior(PREVENT_AUTO_DESTRUCTION); const char *tag = pDestinatonObject->GetObjectTag(); objectContainer.AddReference( tag, pDestinatonObject ); // When we are paring into an object and the object tag is // specified in the XML. For example, when placing: // <Results> // <Customer> // <Widgit> // ... // </Widgit> // </Customer> // </Results> // This will allow us to put Widgit's in a 'Customer' or any // type of object that the pDestinatonObject describes. objectContainer.FromXML(pFactoryXML,this); } else { // When we are paring into an object but that object is not // specified in the XML. For example, when placing: // <Results> // <Widgit> // ... // </Widgit> // </Results> // This will allow us to put Widgit's in a 'Customer' or any // type of object that the pDestinatonObject describes. pDestinatonObject->FromXML(pFactoryXML,this); } } else { XMLObjectFactory factory ( pFactoryXML,m_DataSource->GetServerAddress() ); // Only Queries have result descriptors if ( getResultObjectTag() ) { factory.setResultDescriptor( GetEntry( getResultObjectTag() ) ); } factory.extractObjects(this); } } catch (GException &) { throw; } // in a debug build, this code is better off compiled out so that the debugger will break closer to the problem. // in a release build, this may help to 'crash softer'. #ifndef _DEBUG // if we should catch an unhandled exception here catch ( ... ) { TRACE_ERROR("Fatal Error while factory creating objects" ); TRACE_ERROR("1. Check your String/List Handlers" ); TRACE_ERROR("2. Did you delete a cached object and not remove it from the cache?"); throw GException("XMLProcedureCall", 6); } #endif } else { if (m_bRunObjectFactory) { // we should never get nothing, it may indicate // communication failure depending on the type of DataSource TRACE_WARNING("Nothing received from DataBroker" ); throw GException("XMLProcedureCall", 7); } } return m_strXml; }