//--------------------------------------------------------------------------- #pragma warn -com #include #pragma warn +com #include #pragma hdrstop #include "time.h" #include "pcreposix.h" #include "CopyIteration.h" #include "DataModule.h" #include "DefinedVariable.h" #include "DefinedVariableTable.h" #include "EvaluationContext.h" #include "FieldExpression.h" #include "FileCtrl.hpp" #include "GenerationProperties.h" #include "ICryptographicServerProxy.h" #include "IHash.h" #include "ImportTransactionParameters.h" #include "InitProgress.h" #include "IMessageDigest.h" #include "ISecurityWrapperFactory.h" #include "Iteration.h" #include "IterationConfig.h" #include "IXmlSchemaWrapperElement.h" #include "Login.h" #include "Main.h" #include "ParameterScope.h" #include "ProjectConfig.h" #include "Registry.hpp" #include "RunTests.h" #include "ScenarioParameters.h" #include "Sequence.h" #include "SequenceCollection.h" #include "TestDirectorImport.h" #include "TestHosts.h" #include "TestScenario.h" #include "TestScenarioProperties.h" #include "TestScenarioTemplate.h" #include "TimeEstimate.h" #include "TransactionFieldTemplate.h" #include "TransactionConfig.h" #include "TransactionSpecification.h" #include "TransactionSpecificationValue.h" #include "TransactionSpecificationValueKey.h" #include "TransactionStream.h" #include "TransactionTemplateCollection.h" #include "UdDrainFile.h" #include "Utilities.h" #include #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "Grids_ts" #pragma link "TSDBGrid" #pragma link "TSGrid" #pragma link "TXMLSchema" #pragma link "AdvGrid" #pragma link "BaseGrid" #pragma link "DBAdvGrd" #pragma link "DBAdvNavigator" #pragma link "AdvPageControl" #pragma link "AsgFindDialog" #pragma link "DBAdvGrd" #pragma link "DBAdvGrid" #pragma resource "*.dfm" TMainForm *MainForm; #define TDBADVGRID_FIXED 0 #define INCLUDE_PARENTS TDBADVGRID_FIXED const char *TMainForm::g_headerStructure = "SysHdr_t"; const int TMainForm::g_messagePanel = 0; /** * Process paint message. */ void ProcessPaintMessages( HWND Handle ) { MSG msg; while ( PeekMessage( &msg, Handle, WM_PAINT, WM_PAINT, PM_REMOVE ) ) { DispatchMessage( &msg ); } } //--------------------------------------------------------------------------- const bool __fastcall TMainForm::openSecurityFactory( const char * library ) { m_securityWrapper = ::LoadLibrary( library ); if ( m_securityWrapper ) { m_getSecurityWrapperFactory = reinterpret_cast< getSecurityWrapperFactory_t >( ::GetProcAddress( m_securityWrapper, "getSecurityWrapperFactory" ) ); if ( m_getSecurityWrapperFactory ) { m_securityWrapperFactory = &m_getSecurityWrapperFactory(); if ( m_securityWrapperFactory ) { return ( m_securityWrapperFactory->start() ); } } } return ( false ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::closeSecurityFactory() { if ( m_securityWrapperFactory ) { m_securityWrapperFactory->stop(); m_securityWrapperFactory = 0; } m_getSecurityWrapperFactory = 0; if ( m_securityWrapper ) { ::FreeLibrary( m_securityWrapper ); m_securityWrapper = 0; } } //--------------------------------------------------------------------------- __fastcall TMainForm::TMainForm(TComponent* Owner) : TForm(Owner), m_progressBar( 0 ), m_securityWrapper( 0 ), m_getSecurityWrapperFactory( 0 ), m_securityWrapperFactory( 0 ) { TestCasesTabSheet->TabVisible = false; TestScenariosTabSheet->TabVisible = false; m_Registry = new TRegistry; m_Registry->RootKey = HKEY_CURRENT_USER; if (! m_Registry->OpenKey("\\Software\\ERG\\TxnTestManager", true) ) { m_Registry->CloseKey(); delete m_Registry; m_Registry = NULL; } m_progressBar = new ProgressBar( MainStatusBar ); openSecurityFactory(); } //--------------------------------------------------------------------------- __fastcall TMainForm::~TMainForm() { closeSecurityFactory(); delete m_progressBar; m_progressBar = 0; } //--------------------------------------------------------------------------- void __fastcall TMainForm::ProjectConfigBtnClick(TObject *Sender) { ProjectConfigForm->ShowModal(); LoadProjectCombo(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::IterationConfigBtnClick(TObject *Sender) { if (!m_currentproject.IsEmpty()) { IterationConfigForm->ShowForm(m_currentproject); ProjectsComboBoxChange(this); } } //--------------------------------------------------------------------------- void TMainForm::LoadProjectCombo() { ProjectsComboBox->Clear(); AnsiString mru_project_code; if (m_Registry != NULL) { if (m_Registry->ValueExists("MRUProjectCode")) { mru_project_code = m_Registry->ReadString("MRUProjectCode"); } } TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sql_statement; sql_statement.sprintf("SELECT * FROM PROJECTS"); query->SQL->Text = sql_statement; query->Open(); int mru_item_index = 0; int i=0; while (!query->Eof) { AnsiString name = query->FieldByName("NAME")->AsString; AnsiString *code = new AnsiString(query->FieldByName("PROJECT_CODE")->AsString); if (*code == mru_project_code) { mru_item_index = i; } ProjectsComboBox->AddItem(name, (TObject *)code); i++; query->Next(); } ProjectsComboBox->ItemIndex = mru_item_index; ProjectsComboBoxChange(this); } //--------------------------------------------------------------------------- void __fastcall TMainForm::FormShow(TObject *Sender) { #ifdef LOGGING_ACTIVE ProgrammerLogging::start("TxnTestManager.ini"); #endif if (LoginForm->ShowModal() == mrOk) { try { // Initialise Startup TabSheets TestsPageControl->ActivePage = TestCaseTabSheet; TestParametersPageControl->ActivePage = IterationParametersTabSheet; // Initialise the Database connection Data_Module->IntegrationDBConnection->Connected = false; AnsiString connectionString; connectionString.sprintf( "Provider=OraOLEDB.Oracle.1;Data Source=%s", LoginForm->DatabaseEdit->Text ); Data_Module->IntegrationDBConnection->ConnectionString = connectionString; Data_Module->IntegrationDBConnection->Open(LoginForm->UsernameEdit->Text, LoginForm->PasswordEdit->Text); if (Data_Module->IntegrationDBConnection->Connected) { MASSTxnsQuery->Active = false; TestCaseQuery->Active = false; TestScenariosQuery->Active = false; TxnSpecQuery->Active = false; TxnValuesQuery->Active = false; TxnHdrValuesQuery->Active = false; IterationParamsQuery->Active = false; SequenceGeneratorQuery->Active = false; srand( static_cast< unsigned >( time( 0 ) ) ); int first_rand_seed = rand(); srand( first_rand_seed << (first_rand_seed & 0x00FF) ); // int first_rand = rand(); // Locate the XML SWIS Schema XMLSchema->Active = true; vector schemas; if (XMLSchema->GetSchemas(schemas)) { vector::iterator itr = schemas.begin(); while (itr != schemas.end()) { AnsiString xml_schema = (*itr).c_str(); if (xml_schema.Pos(MASSUDWriter) == 1) { m_xml_schemas.push_back(xml_schema.c_str()); } ++itr; } } if (m_xml_schemas.size() == 0) { MessageDlg("Failed to locate any MASS UD Writer XMLs\n" "Check XMLSchema.ini file", mtError, TMsgDlgButtons() << mbOK, 0); } LoadProjectCombo(); IterationsComboBoxChange(Sender); } else { Close(); } } catch(...) { Close(); } } else { Close(); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::LoadTestCaseNodes(TTreeNode *testcase_node) { bool initially_expanded = testcase_node->Expanded; TestCaseTreeView->Items->BeginUpdate(); testcase_node->DeleteChildren(); TADOQuery *txnquery = new TADOQuery(this); txnquery->Connection = Data_Module->IntegrationDBConnection; AnsiString sql_statement; sql_statement.sprintf("SELECT MASS_TXNS.NAME,TRANSACTION_SPECIFICATION.TXNSPEC_NO " "FROM MASS_TXNS,TRANSACTION_SPECIFICATION " "WHERE TRANSACTION_SPECIFICATION.TESTSCENARIO_NO=%d " "AND MASS_TXNS.PROJECTCODE=TRANSACTION_SPECIFICATION.PROJECT_CODE " "AND MASS_TXNS.ITERATION=TRANSACTION_SPECIFICATION.ITERATION " "AND MASS_TXNS.UDTYPE=TRANSACTION_SPECIFICATION.UDTYPE " "AND MASS_TXNS.UDSUBTYPE=TRANSACTION_SPECIFICATION.UDSUBTYPE " "ORDER BY TRANSACTION_SPECIFICATION.SEQ_NO", (int)testcase_node->Data); txnquery->SQL->Text = sql_statement; txnquery->Open(); while (!txnquery->Eof) { AnsiString txnname = txnquery->FieldByName("NAME")->AsString; int txnspec_no = txnquery->FieldByName("TXNSPEC_NO")->AsInteger; TestCaseTreeView->Items->AddChildObject(testcase_node, txnname.c_str(), (TObject *)txnspec_no); txnquery->Next(); } delete txnquery; if (initially_expanded) { testcase_node->Expand(true); } else { testcase_node->Collapse(true); } TestCaseTreeView->Items->EndUpdate(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::EditTestCaseExecute(TObject *Sender) { // } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewEnter(TObject *Sender) { if (!TestScenariosTabSheet->TabVisible) { TestScenariosTabSheet->TabVisible = true; TestCasesTabSheet->TabVisible = false; } if ( (MainPageControl->ActivePage != TestScenariosTabSheet) && (MainPageControl->ActivePage != ScenarioStepsTabSheet) ) { MainPageControl->ActivePage = TestScenariosTabSheet; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseQueryAfterPost(TDataSet *DataSet) { if (TestCaseQuery->Active) { TestCaseQuery->Close(); } TestCaseQuery->Open(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::loadLegacyHeaderValues( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "FIELDNAME," "FIELDVALUE " "FROM " "TXNHDR_VALUES " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", project.c_str(), iteration ); query->SQL->Text = sqlStatement; query->Open(); AnsiString xpath; AnsiString value; while ( !query->Eof ) { value = query->FieldByName( "FIELDVALUE" )->AsString; if ( !value.IsEmpty() ) { if ( value[ 1 ] == '=' ) { value.Delete( 1, 1 ); } if ( !value.IsEmpty() ) { switch ( value[ 1 ] ) { case '@': value[ 1 ] = '='; if ( FieldExpression::isFunctor( value.c_str() + 1 ) ) { value += "()"; } break; default: break; } } } xpath.sprintf( "/%s/%s", g_headerStructure, query->FieldByName( "FIELDNAME" )->AsString.c_str() ); templates.getTestScenario( 0 ).getField( xpath.c_str() ). setValue( value.c_str() ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::loadLegacyParameters( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "NAME," "FIELDVALUE," "TESTSCENARIO_NO " "FROM " "ITERATION_PARAMS " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", project.c_str(), iteration ); query->SQL->Text = sqlStatement; query->Open(); AnsiString fieldName; int scenario = 0; AnsiString xpath; AnsiString value; while ( !query->Eof ) { fieldName = query->FieldByName( "NAME" )->AsString; scenario = query->FieldByName( "TESTSCENARIO_NO" )->AsInteger; value = query->FieldByName( "FIELDVALUE" )->AsString; if ( !value.IsEmpty() ) { if ( value[ 1 ] == '=' ) { value.Delete( 1, 1 ); } if ( !value.IsEmpty() ) { switch ( value[ 1 ] ) { case '@': value[ 1 ] = '='; if ( FieldExpression::isFunctor( value.c_str() + 1 ) ) { value += "()"; } break; default: break; } } } if ( !fieldName.IsEmpty() ) { switch ( fieldName[ 1 ] ) { case '$': xpath.sprintf( ".*/%s", fieldName.c_str() + 1 ); templates.getTestScenario( scenario ).getField( xpath.c_str() ). setValue( value.c_str() ); break; case '@': // We don't worry about variables here. break; default: break; } } query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionTemplates( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration ) { templates.clear(); loadLegacyHeaderValues( templates, project, iteration ); loadLegacyParameters( templates, project, iteration ); // Now apply our current templates, which override the legacy templates. } //--------------------------------------------------------------------------- const bool __fastcall TMainForm::findSchema( std::string & handle, const AnsiString & projectCode, const int & iteration ) { std::string project; std::string majorVersion; for ( std::vector< std::string >::const_iterator where = m_xml_schemas.begin(); where != m_xml_schemas.end(); ++where ) { if ( XMLSchema->GetAttributeProperty( *where, "project", project ) && ( projectCode == AnsiString( project.c_str() ).UpperCase() ) ) { if ( ( XMLSchema->GetAttributeProperty( *where, "majorversion", majorVersion ) ) && ( iteration == atoi( majorVersion.c_str() ) ) ) { handle = *where; return ( true ); } } } handle.erase(); return ( false ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::IterationsComboBoxChange(TObject *Sender) { AnsiString sql_statement; if ( IterationsComboBox->ItemIndex != -1 ) { const int candidate = reinterpret_cast< int >( IterationsComboBox ->Items ->Objects[ IterationsComboBox->ItemIndex ] ); if ( findSchema( m_schema_handle, m_currentproject.UpperCase(), candidate ) ) { m_currentiteration = candidate; IterationCopyButton->Enabled = true; } else { m_currentiteration = 0; IterationsComboBox->ItemIndex = -1; IterationCopyButton->Enabled = false; } } else { m_currentiteration = 0; } if (m_Registry != NULL) { m_Registry->WriteInteger("MRUProjectIteration", m_currentiteration); } buildTransactionTemplates( m_transactionTemplates, m_currentproject, m_currentiteration ); ApplyTemplates->Enabled = ( m_transactionTemplates.getTemplateCount() > 0 ); // Load the Project/Iterations MASS Txns MASSTxnsQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT * FROM MASS_TXNS WHERE PROJECTCODE='%s' AND ITERATION=%d ORDER BY NAME,UDTYPE,UDSUBTYPE", m_currentproject.c_str(), m_currentiteration); MASSTxnsQuery->SQL->Text = sql_statement; MASSTxnsQuery->Open(); InitialiseMASSTxns(); InitialiseCopyParametersTabSheet( Sender ); // Refresh the TestCases if (TestCaseQuery->Active) { TestCaseQuery->Close(); } TestCaseQuery->Open(); // Load the Project/Iterations Iteration Parameters IterationParamsQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT * FROM ITERATION_PARAMS " "WHERE PROJECT_CODE='%s' AND ITERATION=%d" "AND TESTSCENARIO_NO IS NULL " "ORDER BY NAME", m_currentproject.c_str(), m_currentiteration); IterationParamsQuery->SQL->Text = sql_statement; IterationParamsQuery->Open(); SequenceGeneratorQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT * FROM SEQGEN " "WHERE PROJECT_CODE='%s' AND ITERATION=%d" "ORDER BY SEQNAME", m_currentproject.c_str(), m_currentiteration); SequenceGeneratorQuery->SQL->Text = sql_statement; SequenceGeneratorQuery->Open(); #if 0 // if ( TestScenariosQuery->Active ) { TestScenariosQuery->Close(); } sql_statement=""; sql_statement.sprintf("SELECT * FROM TEST_SCENARIOS " "WHERE PROJECT_CODE='%s' AND ITERATION=%d" "ORDER BY TESTCASE_ID", Utilities::EscapeString( m_currentproject ).c_str(), m_currentiteration); TestScenariosQuery->SQL->Text = sql_statement; TestScenariosQuery->Open(); #endif // Load the Project/Iterations TXNHDR Parameters TxnHdrValuesQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT * FROM TXNHDR_VALUES " "WHERE PROJECT_CODE='%s' AND ITERATION=%d", m_currentproject.c_str(), m_currentiteration); TxnHdrValuesQuery->SQL->Text = sql_statement; TxnHdrValuesQuery->Open(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::ProjectsComboBoxChange(TObject *Sender) { TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; IterationsComboBox->Clear(); // Close our dependent queries if (TestCaseQuery->Active) { TestCaseQuery->Close(); } TestCaseTreeView->Items->Clear(); if ( ProjectsComboBox->ItemIndex != -1 ) { m_currentproject = *(AnsiString *)(ProjectsComboBox->Items->Objects[ProjectsComboBox->ItemIndex]); } if (m_Registry != NULL) { m_Registry->WriteString("MRUProjectCode", m_currentproject); } query->Connection = Data_Module->IntegrationDBConnection; sql_statement=""; sql_statement.sprintf("SELECT TESTTEAM_CODE FROM PROJECTS WHERE PROJECT_CODE='%s'", m_currentproject.c_str() ); query->SQL->Text = sql_statement; query->Open(); m_testteamcode = query->FieldByName("TESTTEAM_CODE")->AsString; query->Close(); sql_statement=""; sql_statement.sprintf("SELECT * FROM ITERATIONS WHERE PROJECT_CODE='%s' ORDER BY ITERATION", m_currentproject.c_str() ); query->SQL->Text = sql_statement; query->Open(); m_currentiteration = 0; int mru_project_iteration = 0; if (m_Registry != NULL) { if (m_Registry->ValueExists("MRUProjectIteration")) { mru_project_iteration = m_Registry->ReadInteger("MRUProjectIteration"); } } /** * Build the iterations available for this project. Include only those * iterations for which schemas have been loaded. */ int index = 0; int mru_project_iteration_index = -1; AnsiString entryString; int iteration = 0; std::string schemaHandle; while (!query->Eof) { iteration = query->FieldByName( "ITERATION" )->AsInteger; if ( findSchema( schemaHandle, m_currentproject.UpperCase(), iteration ) ) { if ( m_currentiteration == 0 ) { m_currentiteration = iteration; } if ( mru_project_iteration == iteration ) { mru_project_iteration_index = index; } entryString.sprintf( "%d", iteration ); IterationsComboBox->AddItem( entryString, reinterpret_cast< TObject * >( iteration ) ); ++index; } query->Next(); } if ( mru_project_iteration_index != -1 ) { IterationsComboBox->ItemIndex = mru_project_iteration_index; IterationsComboBoxChange(Sender); bool allow; TestCaseGridRowChanging(Sender, 0, 1, allow = true ); } else { IterationCopyButton->Enabled = false; } delete query; } //--------------------------------------------------------------------------- void __fastcall TMainForm::tsDBGrid2RowChanged(TObject *Sender, Variant &OldRow, Variant &NewRow) { TestScenariosTabSheet->TabVisible = true; MainPageControl->ActivePage = TestScenariosTabSheet; TestCasesTabSheet->TabVisible = false; } //--------------------------------------------------------------------------- void __fastcall TMainForm::UseCaseDBGridEnter(TObject *Sender) { TestCasesTabSheet->TabVisible = true; MainPageControl->ActivePage = TestCasesTabSheet; TestScenariosTabSheet->TabVisible = false; } //--------------------------------------------------------------------------- void __fastcall TMainForm::IterationParamsQueryAfterInsert( TDataSet *DataSet) { DataSet->FieldByName("PROJECT_CODE")->AsString = m_currentproject; DataSet->FieldByName("ITERATION")->AsInteger = m_currentiteration; } //--------------------------------------------------------------------------- void __fastcall TMainForm::ImportXMLSchemaBtnClick(TObject *Sender) { bool found_xml_schema = false; vector::iterator itr = m_xml_schemas.begin(); while (itr != m_xml_schemas.end()) { string handle = (*itr).c_str(); vector schema_structures; string project; string iteration; XMLSchema->GetAttributeProperty(handle, "project", project); if ( m_currentproject.UpperCase() == AnsiString(project.c_str()).UpperCase() ) { XMLSchema->GetAttributeProperty(handle, "majorversion", iteration); if (m_currentiteration == atoi(iteration.c_str())) { found_xml_schema = true; XMLSchema->GetAttributes(handle, schema_structures); TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; Data_Module->IntegrationDBConnection->BeginTrans(); try { // Disable any constraints query->SQL->Text = "ALTER TABLE TRANSACTION_SPECIFICATION DISABLE CONSTRAINT TRANS_SPEC_MASS_TXNS_C"; query->ExecSQL(); sql_statement.sprintf("DELETE FROM MASS_TXNS WHERE PROJECTCODE='%s' AND ITERATION=%d", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->ExecSQL(); vector::iterator s_itr = schema_structures.begin(); while (s_itr != schema_structures.end()) { string struct_handle = (*s_itr); string specificationonly; string txnname; string udtype; string udsubtype; string documentation; XMLSchema->GetAttributeProperty(struct_handle, "specificationonly", specificationonly); if (specificationonly == "false") { XMLSchema->GetAttributeProperty(struct_handle, "name", txnname); XMLSchema->GetAttributeProperty(struct_handle, "UDType", udtype); XMLSchema->GetAttributeProperty(struct_handle, "UDSubtype", udsubtype); XMLSchema->GetAttributeProperty( struct_handle, "documentation", documentation ); if (udtype.length() > 0) { sql_statement=""; sql_statement.sprintf("INSERT INTO MASS_TXNS(PROJECTCODE,ITERATION,NAME,UDTYPE,UDSUBTYPE,DESCRIPTION) " "VALUES (\'%s\', %d,\'%s\',%d,%d,\'%s\')", m_currentproject.c_str(), m_currentiteration, txnname.c_str(), atoi(udtype.c_str()),atoi(udsubtype.c_str()), Utilities::EscapeString( documentation ).c_str() ); query->SQL->Text = sql_statement; query->ExecSQL(); } } ++s_itr; } // Re-enable any constraints query->SQL->Text = "ALTER TABLE TRANSACTION_SPECIFICATION ENABLE CONSTRAINT TRANS_SPEC_MASS_TXNS_C"; query->ExecSQL(); Data_Module->IntegrationDBConnection->CommitTrans(); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } MASSTxnsQuery->Close(); MASSTxnsQuery->Open(); delete query; } } ++itr; } if (found_xml_schema) { AnsiString msg; msg.sprintf("Imported XML definition for the Project: %s - Iteration: %d", m_currentproject, m_currentiteration); MessageDlg(msg, mtInformation, TMsgDlgButtons() << mbOK, 0); } else { AnsiString msg; msg.sprintf("Failed to locate an XML definition for the Project: %s - Iteration: %d", m_currentproject, m_currentiteration); MessageDlg(msg, mtError, TMsgDlgButtons() << mbOK, 0); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::readTransactionSpecifications( TransactionSpecification & transaction, const int & transactionSpecification ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "XPATH," "FIELDVALUE," "OBSOLETE " "FROM " "TXNSPEC_VALUES " "WHERE " "TXNSPEC_NO=%d", transactionSpecification ); query->SQL->Text = sqlStatement; query->Open(); while ( !query->Eof ) { transaction.addValue( query->FieldByName( "XPATH" )->AsString.c_str(), query->FieldByName( "FIELDVALUE" )->AsString.c_str(), query->FieldByName( "OBSOLETE" )->AsBoolean ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::obsoleteTransactionSpecifications( const TransactionSpecification & transaction ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; for ( std::map< std::string, TransactionSpecificationValue * >::const_iterator where = transaction.getValues().begin(); where != transaction.getValues().end(); ++where ) { if ( where->second->isMarked() ) { if ( where->second->isObsolete() ) { MDETAIL( "Restoring previously obsolete \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); sqlStatement.sprintf( "UPDATE TXNSPEC_VALUES SET " "OBSOLETE='N' " "WHERE " "TXNSPEC_NO=%d AND " "XPATH=\'%s\'", transaction.getTransactionSpecificationNumber(), Utilities::EscapeString( where->second->getXPath() ) ); query->SQL->Text = sqlStatement; if ( query->ExecSQL() != 1 ) { MTHROW( std::runtime_error, \ "Cannot restore previously obsolete field \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); } } } else { if ( where->second->getExpression().length() ) { if ( !where->second->isObsolete() ) { MDETAIL( "Obsoleting \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); sqlStatement.sprintf( "UPDATE TXNSPEC_VALUES SET " "OBSOLETE='Y' " "WHERE " "TXNSPEC_NO=%d AND " "XPATH=\'%s\'", transaction.getTransactionSpecificationNumber(), Utilities::EscapeString( where->second->getXPath() ) ); query->SQL->Text = sqlStatement; if ( query->ExecSQL() != 1 ) { MTHROW( std::runtime_error, \ "Cannot obsolete field \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); } } } else { MDETAIL( "Deleting obsolete and unused \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); sqlStatement.sprintf( "DELETE FROM " "TXNSPEC_VALUES " "WHERE " "TXNSPEC_NO=%d AND " "XPATH=\'%s\'", transaction.getTransactionSpecificationNumber(), Utilities::EscapeString( where->second->getXPath() ) ); query->SQL->Text = sqlStatement; if ( query->ExecSQL() != 1 ) { MTHROW( std::runtime_error, \ "Cannot delete obsolete field \"" \ << where->second->getXPath() \ << "\" of transaction specification " \ << transaction.getTransactionSpecificationNumber() \ << '.' ); } } } } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionsForIteration( TransactionCache & transactionCache, ProgressBar & progressBar, const std::string & schema, const std::string & project, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TXNSPEC_NO," "NAME," "TESTSCENARIO_NO " "FROM " "TRANSACTION_SPECIFICATION," "MASS_TXNS " "WHERE " "TRANSACTION_SPECIFICATION.PROJECT_CODE=\'%s\' AND " "TRANSACTION_SPECIFICATION.ITERATION=%d AND " "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND " "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND " "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND " "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE " "ORDER BY " "TESTSCENARIO_NO," "TXNSPEC_NO", project.c_str(), iteration ); query->SQL->Text = sqlStatement; query->Open(); AnsiString xpath; AnsiString message; while ( !query->Eof ) { if ( !m_transactionCache.isContained( query->FieldByName( "TXNSPEC_NO" )->AsInteger ) ) { message.sprintf( " Building %s ...", query->FieldByName( "NAME" )->AsString.c_str() ); MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message; Application->ProcessMessages(); buildTransactionSpecificationValues( transactionCache, query->FieldByName( "TESTSCENARIO_NO" )->AsInteger, query->FieldByName( "TXNSPEC_NO" )->AsInteger, query->FieldByName( "NAME" )->AsString.c_str(), g_headerStructure, schema, iteration ); } else { message.sprintf( " Using cached %s ...", query->FieldByName( "NAME" )->AsString.c_str() ); MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message; Application->ProcessMessages(); } progressBar.increment(); query->Next(); } } __finally { delete query; query = 0; MainStatusBar->Panels->Items[ g_messagePanel ]->Text = ""; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionsForScenario( TransactionCache & transactionCache, ProgressBar & progressBar, const int & scenario, const std::string & schema, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TXNSPEC_NO," "NAME " "FROM " "TRANSACTION_SPECIFICATION," "MASS_TXNS " "WHERE " "TRANSACTION_SPECIFICATION.TESTSCENARIO_NO=%d AND " "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND " "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND " "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND " "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE " "ORDER BY " "TXNSPEC_NO", scenario ); query->SQL->Text = sqlStatement; query->Open(); AnsiString xpath; AnsiString message; while ( !query->Eof ) { if ( !m_transactionCache.isContained( query->FieldByName( "TXNSPEC_NO" )->AsInteger ) ) { message.sprintf( " Building %s ...", query->FieldByName( "NAME" )->AsString.c_str() ); buildTransactionSpecificationValues( transactionCache, scenario, query->FieldByName( "TXNSPEC_NO" )->AsInteger, query->FieldByName( "NAME" )->AsString.c_str(), g_headerStructure, schema, iteration ); } else { message.sprintf( " Using cached %s ...", query->FieldByName( "NAME" )->AsString.c_str() ); } MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message; Application->ProcessMessages(); progressBar.increment(); query->Next(); } } __finally { delete query; query = 0; MainStatusBar->Panels->Items[ g_messagePanel ]->Text = ""; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionSpecificationValues( TransactionCache & transactionCache, const int & testScenario, const int & transactionSpecification, const std::string & transactionStructureName, const std::string & headerStructureName, const std::string & schema, const int & iteration ) { /** * Ensure that for each transactionSpecification and iteration we do this * only on startup and whenever we import a schema. */ int ordinal = 0; TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; std::string structureHandle; std::string headerHandle; try { if ( XMLSchema->Create( schema.c_str(), transactionStructureName.c_str(), iteration, structureHandle, 0 ) ) { if ( XMLSchema->Create( schema.c_str(), headerStructureName.c_str(), iteration, headerHandle, 0 ) ) { try { Data_Module->IntegrationDBConnection->BeginTrans(); TransactionSpecification & transaction = transactionCache.getTransactionSpecification( transactionSpecification ); readTransactionSpecifications( transaction, transactionSpecification ); buildTransactionSpecificationValues( *query, transactionStructureName, testScenario, transactionSpecification, structureHandle, ordinal = 0, transaction ); buildTransactionSpecificationValues( *query, headerStructureName, testScenario, transactionSpecification, headerHandle, ordinal = 0, transaction ); obsoleteTransactionSpecifications( transaction ); Data_Module->IntegrationDBConnection->CommitTrans(); } catch ( const std::exception & exception ) { std::stringstream stream; stream << "Cannot build transaction specification values for \"" \ << transactionStructureName \ << "\". " \ << exception.what(); MessageDlg( stream.str().c_str(), mtError, TMsgDlgButtons() << mbOK, 0 ); transactionCache.deleteTransactionSpecification( transactionSpecification ); Data_Module->IntegrationDBConnection->RollbackTrans(); } catch ( ... ) { std::stringstream stream; stream << "Cannot build transaction specification values for \"" \ << transactionStructureName \ << "\"."; MessageDlg( stream.str().c_str(), mtError, TMsgDlgButtons() << mbOK, 0 ); transactionCache.deleteTransactionSpecification( transactionSpecification ); Data_Module->IntegrationDBConnection->RollbackTrans(); throw; } } else { std::stringstream stream; stream << "Cannot create structure \"" << headerStructureName << "\" for iteration " << iteration << ". Is \"" << XMLSchema->Profile.c_str() << "\" configured correctly?"; MessageDlg( stream.str().c_str(), mtError, TMsgDlgButtons() << mbOK, 0 ); } } else { std::stringstream stream; stream << "Cannot create structure \"" << transactionStructureName << "\" for iteration " << iteration << ". Is \"" << XMLSchema->Profile.c_str() << "\" configured correctly?"; MessageDlg( stream.str().c_str(), mtError, TMsgDlgButtons() << mbOK, 0 ); } } __finally { XMLSchema->Destroy( headerHandle ); XMLSchema->Destroy( structureHandle ); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionSpecificationFieldValue( TADOQuery & query, const std::string & rootStructure, const std::string & fieldHandle, const int & testScenario, const int & transactionSpecification, int & ordinal, const & childCount, TransactionSpecification & transactions, const int & subscript ) { std::string tagValue; // If we get a tag, then use it. Otherwise, tough luck. if ( !XMLSchema->GetAttributeProperty( fieldHandle, "tag", tagValue ) || tagValue.length() > 0 ) { std::string fieldName; std::string xPath; if ( XMLSchema->GetAttributeProperty( fieldHandle, "name", fieldName ) && XMLSchema->GetAttributeProperty( fieldHandle, "xpath", xPath ) ) { /** * Build the full xpath as the schema reports only the path * relative to the root structure. */ const std::string fullXPath = "/" + rootStructure + xPath; AnsiString displayName; if ( !subscript ) { displayName = fieldName.c_str(); } else { #if TDBADVGRID_FIXED displayName.sprintf( "[%d]", subscript ); #else displayName.sprintf( "%s[%d]", fieldName.c_str(), subscript ); #endif } /** * Work out whether we have to insert or update, and whether we * have to migrate or not. */ bool insert = false; bool migrate = false; if ( transactions.isContained( fullXPath ) ) { insert = false; migrate = false; } else { if ( transactions.isContained( xPath ) ) { insert = false; migrate = true; } else { insert = true; migrate = false; } } /** * We now assert this value into the database. */ std::stringstream stream; if ( !insert ) { if ( !migrate ) { stream << "UPDATE TXNSPEC_VALUES SET " << "CHILD_COUNT=" << childCount << ',' << "DISPLAY_FIELDNAME=\'" << Utilities::EscapeString( displayName ).c_str() << "\'," << "FIELDNAME=\'" << Utilities::EscapeString( fieldName ) << "\'," << "FIELDTAG=" << atoi( tagValue.c_str() ) << ',' << "ORDINAL=" << ++ordinal << ',' << "SUBSCRIPT=" << subscript << ',' << "TESTSCENARIO_NO=" << testScenario << " WHERE " << "TXNSPEC_NO=\'" << transactionSpecification << "\' AND " << "XPATH=\'" << fullXPath << '\''; transactions.markValue( fullXPath ); } else { stream << "UPDATE TXNSPEC_VALUES SET " << "CHILD_COUNT=" << childCount << ',' << "DISPLAY_FIELDNAME=\'" << Utilities::EscapeString( displayName ).c_str() << "\'," << "FIELDNAME=\'" << Utilities::EscapeString( fieldName ) << "\'," << "FIELDTAG=" << atoi( tagValue.c_str() ) << ',' << "ORDINAL=" << ++ordinal << ',' << "SUBSCRIPT=" << subscript << ',' << "TESTSCENARIO_NO=" << testScenario << ',' << "XPATH=\'" << fullXPath << '\'' << " WHERE " << "TXNSPEC_NO=\'" << transactionSpecification << "\' AND " << "XPATH=\'" << xPath << '\''; transactions.markValue( xPath ); } } else { stream << "INSERT INTO TXNSPEC_VALUES ( " "TXNSPEC_NO," "XPATH," "CHILD_COUNT," "DISPLAY_FIELDNAME," "FIELDNAME," "FIELDTAG," "OBSOLETE," "ORDINAL," "SUBSCRIPT," "TESTSCENARIO_NO," "USER_SUPPLIED" " ) VALUES ( " << transactionSpecification << ",\'" << fullXPath << "\'," << childCount << ",\'" << Utilities::EscapeString( displayName ).c_str() << "\',\'" << Utilities::EscapeString( fieldName ).c_str() << "\'," << atoi( tagValue.c_str() ) << ',' << "\'N\'" << ',' << ++ordinal << ',' << subscript << ',' << testScenario << ',' << "\'N\'" << " )"; } query.SQL->Text = stream.str().c_str(); if ( query.ExecSQL() != 1 ) { MTHROW( std::runtime_error, \ "Cannot update field \"" \ << fullXPath \ << "\" of transaction specification " \ << transactionSpecification \ << '.' ); } } else { MTHROW( std::runtime_error, \ "Cannot get name and xpath for schema element \"" \ << fieldHandle \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot get tag value for schema element \"" \ << fieldHandle \ << "\". The tag is present but has a zero-length value." ); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionSpecificationRepeatValue( TADOQuery & query, const std::string & rootStructure, const std::string & attribute, const int & testScenario, const int & transactionSpecification, const std::string & transactionStructureHandle, int & ordinal, TransactionSpecification & transactions, const int & repeatLimit ) { std::string refcountField; std::string repeatSize; /** * Find the upper bound of the repeat by looking for the "max" property * of the "refcountfield" (possibly an xPath), and then for our * "maxOccurs" property. */ XMLSchema->GetAttributeProperty( attribute, "refcountfield", refcountField ); if ( refcountField.length() ) { XMLSchema->GetAttributeProperty( transactionStructureHandle + "." + refcountField, "max", repeatSize ); } if ( !repeatSize.length() ) { XMLSchema->GetAttributeProperty( attribute, "maxOccurs", repeatSize ); } if ( repeatSize.length() ) { /** * Now instantiate the array so that we may traverse it, but limit it to * repeatLimit elements. */ const int size = std::min< int >( atoi( repeatSize.c_str() ), repeatLimit ); std::string repeatName; if ( ( refcountField.length() == 0 ) || XMLSchema->SetAttributeValue( transactionStructureHandle, refcountField, size ) ) { if ( XMLSchema->GetAttributeProperty( attribute, "name", repeatName ) ) { AnsiString repeatElement; std::string datatype; repeatElement.sprintf( "%s.1.%s", attribute.c_str(), repeatName.c_str() ); if ( XMLSchema->GetAttributeProperty( repeatElement.c_str(), "datatype", datatype ) ) { const bool isStruct = ( datatype == "Struct" ); buildTransactionSpecificationFieldValue( query, rootStructure, attribute, testScenario, transactionSpecification, ordinal, countChildren( attribute, isStruct ), transactions ); if ( size >= 1 ) { std::string repeatHandle; for ( int where = 1; where <= size; ++where ) { repeatElement.sprintf( "%s.%d.%s", attribute.c_str(), where, repeatName.c_str() ); repeatHandle = repeatElement.c_str(); if ( isStruct ) { buildTransactionSpecificationFieldValue( query, rootStructure, repeatHandle, testScenario, transactionSpecification, ordinal, countChildren( repeatHandle, isStruct ), transactions, where ); buildTransactionSpecificationValues( query, rootStructure, testScenario, transactionSpecification, repeatHandle, ordinal, transactions ); } else { buildTransactionSpecificationFieldValue( query, rootStructure, repeatHandle, testScenario, transactionSpecification, ordinal, 0, transactions, where ); } } } } else { MTHROW( std::runtime_error, \ "Cannot get datatype for schema element \"" \ << repeatElement.c_str() \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot get name for schema element \"" \ << attribute \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot set size for schema element \"" \ << transactionStructureHandle + "." + refcountField \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot get repeat size for schema element \"" \ << attribute \ << "\"." ); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionSpecificationValues( TADOQuery & query, const std::string & rootStructure, const int & testScenario, const int & transactionSpecification, const std::string & transactionStructureHandle, int & ordinal, TransactionSpecification & transactions ) { std::vector< std::string > attributes; if ( XMLSchema->GetAttributes( transactionStructureHandle, attributes ) ) { std::string elementType; for ( std::vector< std::string >::iterator where = attributes.begin(); where != attributes.end(); ++where ) { if ( XMLSchema->GetAttributeProperty( *where, "type", elementType ) ) { std::string elementDatatype; if ( elementType == "field" ) { if ( XMLSchema->GetAttributeProperty( *where, "datatype", elementDatatype ) ) { const isStruct = ( elementDatatype == "Struct" ); buildTransactionSpecificationFieldValue( query, rootStructure, *where, testScenario, transactionSpecification, ordinal, ( isStruct ? countChildren( *where, false ) : 0 ), transactions ); if ( isStruct ) { buildTransactionSpecificationValues( query, rootStructure, testScenario, transactionSpecification, *where, ordinal, transactions ); } } else { MTHROW( std::runtime_error, \ "Cannot get datatype for schema element \"" \ << *where \ << "\"." ); } } else if ( elementType == "repeat" ) { buildTransactionSpecificationRepeatValue( query, rootStructure, *where, testScenario, transactionSpecification, transactionStructureHandle, ordinal, transactions ); } } else { MTHROW( std::runtime_error, \ "Cannot get type for schema element \"" \ << *where \ << "\"." ); } } } else { MTHROW( std::runtime_error, \ "Cannot get attributes for schema element \"" \ << transactionStructureHandle \ << "\"." ); } } //--------------------------------------------------------------------------- const unsigned __fastcall TMainForm::countChildren( const std::string & transactionStructureHandle, const bool & isStructureRepeat ) { unsigned childCount = 0; std::vector< std::string > attributes; if ( XMLSchema->GetAttributes( transactionStructureHandle, attributes ) ) { std::string elementType; std::string elementDatatype; for ( std::vector< std::string >::iterator where = attributes.begin(); where != attributes.end(); ++where ) { if ( XMLSchema->GetAttributeProperty( *where, "type", elementType ) ) { // if ( !isStructureRepeat ) // { ++childCount; // } if ( elementType == "field" ) { if ( XMLSchema->GetAttributeProperty( *where, "datatype", elementDatatype ) ) { if ( elementDatatype == "Struct" ) { childCount += countChildren( *where, false ); } } else { MTHROW( std::runtime_error, \ "Cannot get datatype for schema element \"" \ << *where \ << "\"." ); } } else if ( elementType == "repeat" ) { childCount += countChildren( *where, transactionStructureHandle ); } } else { MTHROW( std::runtime_error, \ "Cannot get type for schema element \"" \ << *where \ << "\"." ); } } } else { MTHROW( std::runtime_error, \ "Cannot get attributes for schema element \"" \ << transactionStructureHandle \ << "\"." ); } return ( childCount ); } //--------------------------------------------------------------------------- const unsigned __fastcall TMainForm::countChildren( const std::string & attribute, const std::string & transactionStructureHandle, const int & repeatLimit ) { unsigned childCount = 0; std::string refcountField; std::string repeatSize; /** * Find the upper bound of the repeat by looking for the "max" property * of the "refcountfield" (possibly an xPath), and then for our * "maxOccurs" property. */ XMLSchema->GetAttributeProperty( attribute, "refcountfield", refcountField ); if ( refcountField.length() ) { XMLSchema->GetAttributeProperty( transactionStructureHandle + "." + refcountField, "max", repeatSize ); } if ( !repeatSize.length() ) { XMLSchema->GetAttributeProperty( attribute, "maxOccurs", repeatSize ); } if ( repeatSize.length() ) { /** * Now instantiate the array so that we may traverse it, but limit it to * repeatLimit elements. */ const int size = std::min< int >( atoi( repeatSize.c_str() ), repeatLimit ); std::string repeatName; if ( ( refcountField.length() == 0 ) || XMLSchema->SetAttributeValue( transactionStructureHandle, refcountField, size ) ) { if ( XMLSchema->GetAttributeProperty( attribute, "name", repeatName ) ) { if ( size >= 1 ) { AnsiString repeatElement; std::string datatype; repeatElement.sprintf( "%s.1.%s", attribute.c_str(), repeatName.c_str() ); if ( XMLSchema->GetAttributeProperty( repeatElement.c_str(), "datatype", datatype ) ) { const isStruct = ( datatype == "Struct" ); for ( int where = 1; where <= size; ++where ) { repeatElement.sprintf( "%s.%d.%s", attribute.c_str(), where, repeatName.c_str() ); if ( !isStruct ) { ++childCount; } else { childCount += countChildren( repeatElement.c_str(), false ) + 1; } } } else { MTHROW( std::runtime_error, \ "Cannot get datatype for schema element \"" \ << repeatElement.c_str() \ << "\"." ); } } } else { MTHROW( std::runtime_error, \ "Cannot get name for schema element \"" \ << attribute \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot set size for schema element \"" \ << transactionStructureHandle + "." + refcountField \ << "\"." ); } } else { MTHROW( std::runtime_error, \ "Cannot get repeat size for schema element \"" \ << attribute \ << "\"." ); } return ( childCount ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::clearTransactionSpecificationValueTree( TDBAdvGrid & grid ) { #if TDBADVGRID_FIXED grid.RemoveAllNodes(); #endif } //--------------------------------------------------------------------------- const int TMainForm::countChildNodes( TDBAdvGrid & grid, TADOQuery & query, const int & row, const int & rows ) { query.RecNo = row; // Move the cursor to the row we're looking at. int count = 0; const AnsiString parentPath = query.FieldByName( "XPATH" )->AsString; for ( int where = row + 1; where <= rows; ++where ) { query.RecNo = where; if ( parentPath == query.FieldByName( "XPATH" ) ->AsString.SubString( 1, parentPath.Length() ) ) { ++count; } else { break; } } return ( count ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildTransactionSpecificationValueTree( TDBAdvGrid & grid, TADOQuery & query ) { #if TDBADVGRID_FIXED grid.BeginUpdate(); const int currentRow = query.RecNo; try { int children = 0; const int rows = query.RecordCount; for ( int where = 1; where <= rows; ++where ) { if ( ( children = countChildNodes( grid, query, where, rows ) ) > 0 ) { grid.AddNode( where, 1 + children ); } } } __finally { grid.ContractAll(); query.RecNo = currentRow; grid.EndUpdate(); } #endif } //--------------------------------------------------------------------------- void __fastcall TMainForm::getParentOrdinals( std::vector< int > & parents ) { TADOQuery * query = 0; try { parents.clear(); query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "ORDINAL " "FROM " "TXNSPEC_VALUES " "WHERE " "TESTSCENARIO_NO=%d AND " "TXNSPEC_NO=%d AND " "CHILD_COUNT > 0", m_testscenario_no, m_txnspec_no ); query->SQL->Text = sqlStatement; query->Open(); while ( !query->Eof ) { parents.push_back( query->FieldByName( "ORDINAL" )->AsInteger ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::populatePayloadStructureTab( const AnsiString & structure ) { AnsiString sqlStatement; PayloadStructureTabSheet->TabVisible = true; PayloadStructureTabSheet->Caption = structure; TxnValuesQuery->Close(); #if TDBADVGRID_FIXED clearTransactionSpecificationValueTree( *NewPayloadStructureGrid ); #endif sqlStatement.sprintf( "SELECT " "* " "FROM " "TXNSPEC_VALUES " "WHERE " "TESTSCENARIO_NO=%d AND " "TXNSPEC_NO=%d AND " "XPATH LIKE \'/%s/%%\' AND " "OBSOLETE=\'N\' " #if !INCLUDE_PARENTS "AND CHILD_COUNT=0 " #endif "ORDER BY " "ORDINAL," "FIELDNAME," "SUBSCRIPT", m_testscenario_no, m_txnspec_no, structure.c_str() ); TxnValuesQuery->SQL->Text = sqlStatement; TxnValuesQuery->Open(); #if TDBADVGRID_FIXED buildTransactionSpecificationValueTree( *NewPayloadStructureGrid, *TxnValuesQuery ); #endif #if INCLUDE_PARENTS getParentOrdinals( m_parents ); #endif } //--------------------------------------------------------------------------- void __fastcall TMainForm::populateHeaderStructureTab( const AnsiString & structure ) { AnsiString sqlStatement; // HeaderStructureTabSheet->TabVisible = true; HeaderStructureTabSheet->Caption = structure; TxnHeaderValuesQuery->Close(); sqlStatement.sprintf( "SELECT " "* " "FROM " "TXNSPEC_VALUES " "WHERE " "TESTSCENARIO_NO=%d AND " "TXNSPEC_NO=%d AND " "XPATH LIKE \'/%s/%%\' AND " "OBSOLETE=\'N\' " "ORDER BY " "ORDINAL," "FIELDNAME," "SUBSCRIPT", m_testscenario_no, m_txnspec_no, structure.c_str() ); TxnHeaderValuesQuery->SQL->Text = sqlStatement; TxnHeaderValuesQuery->Open(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::populateObsoleteStructureTab( void ) { AnsiString sqlStatement; TxnObsoleteValuesQuery->Close(); sqlStatement.sprintf( "SELECT " "* " "FROM " "TXNSPEC_VALUES " "WHERE " "TESTSCENARIO_NO=%d AND " "TXNSPEC_NO=%d AND " "OBSOLETE=\'Y\'" "ORDER BY " "ORDINAL," "FIELDNAME," "SUBSCRIPT", m_testscenario_no, m_txnspec_no ); TxnObsoleteValuesQuery->SQL->Text = sqlStatement; TxnObsoleteValuesQuery->Open(); ObsoleteFieldTabSheet->TabVisible = !TxnObsoleteValuesQuery->IsEmpty(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewChange(TObject *Sender, TTreeNode *Node) { TestCaseTreeViewEnter(Sender); AnsiString sql_statement; // Only update when TestCase nodes if (Node->Level == 0) { // ----------------- TEST CASE ----------------- TestCasePanel->Caption = Node->Text; m_testscenario_no = (int)(Node->Data); m_txnspec_no = 0; m_structure_name=""; TxnValuesQuery->Close(); TxnHeaderValuesQuery->Close(); TxnObsoleteValuesQuery->Close(); // TransactionStructurePageControl->ActivePage = PayloadStructureTabSheet; PayloadStructureTabSheet->Caption = "Payload Structure"; HeaderStructureTabSheet->Caption = "Header Structure"; // HeaderStructureTabSheet->TabVisible = false; ObsoleteFieldTabSheet->TabVisible = false; m_parents.clear(); TxnStepsQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT NAME,DESCRIPTION,EXPECTED_RESULT FROM TXNSPEC_STEPS " "WHERE TESTSCENARIO_NO=%d " "ORDER BY NAME", m_testscenario_no); TxnStepsQuery->SQL->Text = sql_statement; TxnStepsQuery->Open(); // --------------------------------------------- } else if (Node->Level == 1) { // ---------------- TRANSACTION ---------------- TestCasePanel->Caption = Node->Parent->Text; m_testscenario_no = (int)(Node->Parent->Data); m_txnspec_no = (int)(Node->Data); m_structure_name = Node->Text.c_str(); // TransactionStructurePageControl->ActivePage = PayloadStructureTabSheet; if ( !m_transactionCache.isContained( m_txnspec_no ) ) { const TCursor Save_Cursor = Screen->Cursor; try { Screen->Cursor = crHourGlass; AnsiString message; message.sprintf( " Building %s ...", Node->Text.c_str() ); MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message; Application->ProcessMessages(); buildTransactionSpecificationValues( m_transactionCache, m_testscenario_no, m_txnspec_no, Node->Text.c_str(), g_headerStructure, m_schema_handle, m_currentiteration ); } __finally { Screen->Cursor = Save_Cursor; } } MainStatusBar->Panels->Items[ g_messagePanel ]->Text = ""; populateHeaderStructureTab( g_headerStructure ); populatePayloadStructureTab( Node->Text ); populateObsoleteStructureTab(); TxnStepsQuery->Close(); sql_statement=""; sql_statement.sprintf("SELECT NAME,DESCRIPTION,EXPECTED_RESULT FROM TXNSPEC_STEPS " "WHERE TESTSCENARIO_NO=%d " "ORDER BY NAME", m_testscenario_no); TxnStepsQuery->SQL->Text = sql_statement; TxnStepsQuery->Open(); // --------------------------------------------- } } //--------------------------------------------------------------------------- void __fastcall TMainForm::NewTransactionActionExecute(TObject *Sender) { TTreeNode *current_node = TestCaseTreeView->Selected; if (current_node != NULL) { if (current_node->Level == 0) // Add Txn { AnsiString testcase_text = current_node->Text; int testscenario_no = (int)(current_node->Data); if ( TxnConfig->ShowForm(m_currentproject, m_currentiteration, testcase_text) == true) { TxnSpecQuery->Close(); TADOQuery * query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); sql_statement=""; sql_statement.sprintf("SELECT MAX(SEQ_NO) AS MAXSEQ_NO " "FROM TRANSACTION_SPECIFICATION " "WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTSCENARIO_NO=%d", m_currentproject.c_str(), m_currentiteration, testscenario_no); query->SQL->Text = sql_statement; query->Open(); int seq_no = query->FieldByName("MAXSEQ_NO")->AsInteger; seq_no++; vector selected_txns = TxnConfig->getSelectedTxns(); vector::iterator selected_txn_itr = selected_txns.begin(); while (selected_txn_itr != selected_txns.end()) { unsigned int txnindex = (*selected_txn_itr); unsigned short udtype = txnindex >> 16; unsigned short udsubtype = txnindex & 0xffff; sql_statement=""; sql_statement.sprintf("INSERT INTO TRANSACTION_SPECIFICATION (PROJECT_CODE,ITERATION,TESTSCENARIO_NO,UDTYPE,UDSUBTYPE,SEQ_NO) " "VALUES ('%s',%d,%d,%d,%d,%d) ", m_currentproject.c_str(), m_currentiteration, testscenario_no, udtype, udsubtype, seq_no); query->SQL->Text = sql_statement; query->ExecSQL(); seq_no++; selected_txn_itr++; } Data_Module->IntegrationDBConnection->CommitTrans(); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; TxnSpecQuery->Open(); LoadTestCaseNodes(current_node); } } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::DeleteTransactionActionExecute(TObject *Sender) { bool refresh_testcases = false; for (unsigned selected_item=0; selected_itemSelectionCount; selected_item++) { TTreeNode *current_node = TestCaseTreeView->Selections[selected_item]; if (current_node!= NULL) { if (current_node->Level == 1) // Remove Test Case Transaction { // Confirm deletion AnsiString message; message.sprintf( "Are you sure you want to delete this transaction?" ); if ( MessageDlg( message, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes ) { int testscenario_no = (int)(current_node->Parent->Data); int txnspec_no = (int)(current_node->Data); TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES " "WHERE TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d", testscenario_no, txnspec_no); query->SQL->Text = sql_statement; query->ExecSQL(); sql_statement=""; sql_statement.sprintf("DELETE FROM TRANSACTION_SPECIFICATION " "WHERE PROJECT_CODE='%s' AND ITERATION=%d " "AND TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d ", m_currentproject.c_str(), m_currentiteration, testscenario_no, txnspec_no); query->SQL->Text = sql_statement; query->ExecSQL(); Data_Module->IntegrationDBConnection->CommitTrans(); refresh_testcases = true; ResequenceTransactions(current_node->Parent); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; } } } } if (refresh_testcases) { bool allow; TestCaseGridRowChanging(Sender, 0, 1, allow = true); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseZoomInClick(TObject *Sender) { TestCaseTreeView->FullExpand(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseZoomOutClick(TObject *Sender) { TestCaseTreeView->FullCollapse(); } //--------------------------------------------------------------------------- AnsiString & TMainForm::getNameFromNode( AnsiString & name, const AnsiString & string ) { char const *p = string.c_str(); name = string; if ( *p && *p == '(' ) { ++p; while ( *p && isdigit( *p ) ) { ++p; } if ( *p && *p == ')' ) { ++p; while ( *p && isspace( *p ) ) { ++p; } if ( *p ) { name = p; } } } return ( name ); } // Add a New Use Case void __fastcall TMainForm::AddTestCaseNodeClick(TObject *Sender) { TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); sql_statement=""; sql_statement.sprintf("SELECT MAX(TESTCASE_SEQNO) MAX_SEQNO FROM TEST_SCENARIOS " "WHERE PROJECT_CODE='%s' AND ITERATION=%d", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->Open(); int max_testcase_seqno = query->FieldByName("MAX_SEQNO")->AsInteger; sql_statement=""; sql_statement.sprintf("INSERT INTO TEST_SCENARIOS (PROJECT_CODE,ITERATION,USECASE,TESTCASE_ID,DESCRIPTION,TESTCASE_SEQNO) " "VALUES ('%s',%d,'%s','%s','%s',%d) ", m_currentproject.c_str(), m_currentiteration, Utilities::EscapeString( TestCaseQuery->FieldByName("USECASE_ID")->AsString ).c_str(), Utilities::EscapeString( TestCaseQuery->FieldByName("TESTCASE_ID")->AsString ).c_str(), Utilities::EscapeString( TestCaseQuery->FieldByName("DESCRIPTION")->AsString ).c_str(), max_testcase_seqno+1); query->SQL->Text = sql_statement; query->ExecSQL(); Data_Module->IntegrationDBConnection->CommitTrans(); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; bool allow; TestCaseGridRowChanging(Sender, 0, 1, allow = true); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewEndDrag(TObject *Sender, TObject *Target, int X, int Y) { TTreeNode* target_node = TestCaseTreeView->GetNodeAt(X, Y); if (target_node != NULL) { if (target_node->Level == 0) // Test Case Movement { TestCaseTreeView->Items->BeginUpdate(); AnsiString source_node_text = m_startnode->Text; TTreeNode *newnode = TestCaseTreeView->Items->Insert(target_node, source_node_text); newnode->Data = m_startnode->Data; TestCaseTreeView->Items->Delete(m_startnode); m_startnode = NULL; TestCaseTreeView->Items->EndUpdate(); // Test Case Node TTreeNode *testcase_node = target_node; ResequenceTestCases(testcase_node); bool allow; TestCaseGridRowChanging(Sender, 0, 1, allow = true); } else if (target_node->Level == 1) // Test Scenario Movement { TestCaseTreeView->Items->BeginUpdate(); AnsiString source_node_text = m_startnode->Text; TTreeNode *newnode = TestCaseTreeView->Items->Insert(target_node, source_node_text); newnode->Data = m_startnode->Data; TestCaseTreeView->Items->Delete(m_startnode); m_startnode = NULL; TestCaseTreeView->Items->EndUpdate(); // Test Case Node TTreeNode *testcase_node = target_node->Parent; ResequenceTransactions(testcase_node); LoadTestCaseNodes(testcase_node); } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ResequenceTestCases(TTreeNode *testcase_node) { // Resequence Subtree nodes TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); int testcaseseqno = 1; for (int i=0; iItems->Count; i++) { TTreeNode* childnode = TestCaseTreeView->Items->Item[i]; if (childnode->Level == 0) // Only consider TestCase Nodes { int testscenario_no = (int)(childnode->Data); sql_statement=""; sql_statement.sprintf("UPDATE TEST_SCENARIOS SET TESTCASE_SEQNO=%d " "WHERE TESTSCENARIO_NO=%d", testcaseseqno, testscenario_no); query->SQL->Text = sql_statement; query->ExecSQL(); testcaseseqno++; } } Data_Module->IntegrationDBConnection->CommitTrans(); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; } //--------------------------------------------------------------------------- void __fastcall TMainForm::ResequenceTransactions(TTreeNode *testcase_node) { // Resequence Subtree nodes TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); int testscenario_no = (int)(testcase_node->Data); for (int i=0; iCount; i++) { sql_statement=""; sql_statement.sprintf("UPDATE TRANSACTION_SPECIFICATION SET SEQ_NO=%d " "WHERE PROJECT_CODE='%s' AND ITERATION=%d " "AND TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d", i+1, m_currentproject.c_str(), m_currentiteration, testscenario_no, testcase_node->Item[i]->Data); query->SQL->Text = sql_statement; query->ExecSQL(); } Data_Module->IntegrationDBConnection->CommitTrans(); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewStartDrag(TObject *Sender, TDragObject *&DragObject) { m_startnode = TestCaseTreeView->Selected; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewDragOver(TObject *Sender, TObject *Source, int X, int Y, TDragState State, bool &Accept) { if (dynamic_cast(Source) != NULL) { Accept = true; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ApplyTemplatesClick(TObject *Sender) { const TCursor Save_Cursor = Screen->Cursor; try { Screen->Cursor = crHourGlass; try { TADOQuery * query = 0; try { const unsigned count = countTransactionsInIteration( m_currentproject.c_str(), m_currentiteration ); m_progressBar->open( count * 2 + 1 ); // Rebuild the transaction templates, they may have changed. buildTransactionTemplates( m_transactionTemplates, m_currentproject, m_currentiteration ); m_progressBar->increment(); buildTransactionsForIteration( m_transactionCache, *m_progressBar, m_schema_handle, m_currentproject.c_str(), m_currentiteration ); query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TESTSCENARIO_NO " "" "FROM " "TEST_SCENARIOS " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", m_currentproject.c_str(), m_currentiteration ); query->SQL->Text = sqlStatement; query->Open(); try { Data_Module->IntegrationDBConnection->BeginTrans(); while ( !query->Eof ) { applyTemplatesToScenario( *m_progressBar, query->FieldByName( "TESTSCENARIO_NO" )->AsInteger ); query->Next(); } Data_Module->IntegrationDBConnection->CommitTrans(); if ( TxnValuesQuery->State != dsInactive ) { TxnValuesQuery->Refresh(); HeaderStructureGrid->Invalidate(); } if ( TxnHeaderValuesQuery->State != dsInactive ) { TxnHeaderValuesQuery->Refresh(); TransactionValueGrid->Invalidate(); } if ( TxnObsoleteValuesQuery->State != dsInactive ) { TxnObsoleteValuesQuery->Refresh(); ObsoleteFieldGrid->Invalidate(); } } catch ( ... ) { Data_Module->IntegrationDBConnection->RollbackTrans(); throw; } } __finally { delete query; query = 0; m_progressBar->close(); } } catch ( const std::exception & exception ) { MessageDlg( exception.what(), mtError, TMsgDlgButtons() << mbOK, 0 ); } catch ( ... ) { MessageDlg( "Unknown exception applying templates to this scenario.", mtError, TMsgDlgButtons() << mbOK, 0 ); } } __finally { Screen->Cursor = Save_Cursor; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::InitialiseMASSTxns() { AnsiString sql_statement; TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; m_mass_txns.clear(); try { sql_statement=""; sql_statement.sprintf("SELECT NAME,UDTYPE,UDSUBTYPE " "FROM MASS_TXNS " "WHERE PROJECTCODE='%s' " "AND ITERATION=%d ", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->Open(); while (!query->Eof) { unsigned short udtype = query->FieldByName("UDTYPE")->AsInteger; unsigned short udsubtype = query->FieldByName("UDSUBTYPE")->AsInteger; unsigned int udindex = (udtype << 16) + udsubtype; TXNIndexPair pair(udindex, query->FieldByName("NAME")->AsString); m_mass_txns.insert(pair); query->Next(); } } __finally { delete query; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::InitialiseTxnParams(unsigned int schema_format_version, IterationParams &iteration_params, IterationSequences &iteration_sequences) { AnsiString sql_statement; // Format Version only encodes Major/Minor numbers, and not Patch Level AnsiString formatversion; formatversion.sprintf("0x%08X", schema_format_version); IterationParamsPair pair("#0_@FORMATVERSION", formatversion.c_str()); iteration_params.insert(pair); TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; TADOQuery *seqquery = new TADOQuery(this); seqquery->Connection = Data_Module->IntegrationDBConnection; try { sql_statement=""; sql_statement.sprintf("SELECT * FROM ITERATION_PARAMS " "WHERE PROJECT_CODE='%s' AND ITERATION=%d", m_currentproject.c_str(), m_currentiteration); query->SQL->Text = sql_statement; query->Open(); while (!query->Eof) { int testscenario_no = 0; string fieldvalue = query->FieldByName("FIELDVALUE")->AsString.c_str(); if ( !query->FieldByName("TESTSCENARIO_NO")->IsNull ) { testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger; } // Format is: @SEQ(,,,) if (fieldvalue.substr(0,4) == "@SEQ") { int lpos = fieldvalue.find("(")+1; int rpos = fieldvalue.rfind(")"); string seqargs = fieldvalue.substr( lpos, rpos ); string seqname; string seqstart; string seqinc; string seqlimit; const char *p = seqargs.c_str(); while ( (*p != '\0') && (*p == ' ') ) p++; // Skip Whitespace while ( (*p != '\0') && (*p != ',') && (*p != ' ') ) { seqname += *p; p++; } if (*p != '\0') p++; while ( (*p != '\0') && (*p == ' ') ) { p++; // Skip Whitespace } while ( (*p != '\0') && (*p != ',') && (*p != ' ') ) { seqstart += *p; p++; } if (*p != '\0') p++; while ( (*p != '\0') && (*p == ' ') ) { p++; // Skip Whitespace } while ( (*p != '\0') && (*p != ',') && (*p != ' ') ) { seqinc += *p; p++; } if (*p != '\0') p++; while ( (*p != '\0') && (*p == ' ') ) { p++; // Skip Whitespace } while (*p != '\0') { seqlimit += *p; p++; } IterationSequence sequence; sequence.name = seqname; if (seqstart.length() > 0) { sequence.initial_value = atoi(seqstart.c_str()); } else { sequence.initial_value = 0; } if (seqname[0] == '#') { string seqgenname = seqname.substr(1,seqname.length()-1); sql_statement=""; sql_statement.sprintf("SELECT SEQVALUE FROM SEQGEN WHERE PROJECT_CODE='%s' AND ITERATION=%d AND SEQNAME='%s'", m_currentproject.c_str(), m_currentiteration, seqgenname.c_str() ); seqquery->SQL->Text = sql_statement; seqquery->Open(); if (seqquery->RecordCount == 0) { sql_statement=""; sql_statement.sprintf("INSERT INTO SEQGEN (PROJECT_CODE,ITERATION,SEQNAME,SEQVALUE) VALUES ('%s',%d,'%s',%d)", m_currentproject.c_str(), m_currentiteration, seqgenname.c_str(), sequence.initial_value ); seqquery->SQL->Text = sql_statement; seqquery->ExecSQL(); } else { sequence.initial_value = seqquery->FieldByName("SEQVALUE")->AsInteger; } } sequence.value = sequence.initial_value; if (seqinc.length() > 0) { sequence.increment = atoi(seqinc.c_str()); } else { sequence.increment = 1; } if (seqlimit.length() > 0) { sequence.reset_at = atoi(seqlimit.c_str()); } else { sequence.reset_at = 0; } sequence.reset_at = 0; IterationSequencesPair seqpair(sequence.name, sequence); iteration_sequences.insert(seqpair); } AnsiString param_name; param_name.sprintf("#%d_%s", testscenario_no, query->FieldByName("NAME")->AsString.c_str()); IterationParamsPair pair2(param_name.c_str(), fieldvalue.c_str()); iteration_params.insert(pair2); query->Next(); } } __finally { delete query; delete seqquery; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::InitialiseTestScenario(unsigned int testscenario_no, TxnSpecValueMap &txnSpecValueMap, FoundTxnSpecValueMap &foundTxnSpecValueMap, IterationSequences &iteration_sequences, IterationParams &iteration_params) { AnsiString sql_statement; TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; TADOQuery *values_query = new TADOQuery(this); values_query->Connection = Data_Module->IntegrationDBConnection; try { sql_statement=""; sql_statement.sprintf("select txnspec_no,udtype,udsubtype " "from transaction_specification " "where testscenario_no=%d order by seq_no", testscenario_no); query->SQL->Text = sql_statement; query->Open(); while (!query->Eof) { // For each transaction unsigned int txnspec_no = query->FieldByName("TXNSPEC_NO")->AsInteger; unsigned short udtype = query->FieldByName("UDTYPE")->AsInteger; unsigned short udsubtype = query->FieldByName("UDSUBTYPE")->AsInteger; unsigned int udindex = (udtype << 16) + udsubtype; TXNIndexMap::iterator txn_itr = m_mass_txns.find(udindex); if (txn_itr != m_mass_txns.end()) { string structure_name; string structure_handle; structure_name = (*txn_itr).second.c_str(); // Create a Transaction Instance if (XMLSchema->Create(m_schema_handle.c_str(), structure_name.c_str(), m_currentiteration, structure_handle, NULL)) { ProcessTxnStructure(structure_handle, udtype, udsubtype, testscenario_no, txnspec_no, values_query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, 0); XMLSchema->Destroy(structure_handle); } else { AnsiString msg; msg.sprintf("Failed to create schema object for Schema: '%s' Structure: '%s'", m_schema_handle.c_str(), structure_name.c_str()); MessageDlg(msg, mtError, TMsgDlgButtons() << mbOK, 0); } } // Found Transaction declaration in MASS TXNS query->Next(); } } __finally { delete query; delete values_query; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ProcessTxnStructure(string structure_handle, unsigned short udtype, unsigned short udsubtype, int testscenario_no, int txnspec_no, TADOQuery *query, TxnSpecValueMap &txnSpecValueMap, FoundTxnSpecValueMap &foundTxnSpecValueMap, IterationParams &iteration_params, IterationSequences &iteration_sequences, unsigned int nested_subscript) { vector structure_attributes; vector::iterator s_itr; AnsiString sql_statement; XMLSchema->GetAttributes(structure_handle, structure_attributes); s_itr = structure_attributes.begin(); while (s_itr != structure_attributes.end()) { string attribute_handle = (*s_itr); string elementtype; XMLSchema->GetAttributeProperty(attribute_handle, "type", elementtype); if (elementtype == "field") { string datatype; XMLSchema->GetAttributeProperty(attribute_handle, "datatype", datatype); if (datatype == "Struct") { ProcessTxnStructure(attribute_handle, udtype, udsubtype, testscenario_no, txnspec_no, query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, 0); } else { string fieldname; string tagvalue; string xpath; XMLSchema->GetAttributeProperty(attribute_handle, "tag", tagvalue); if (tagvalue.length() > 0) { XMLSchema->GetAttributeProperty(attribute_handle, "name", fieldname); XMLSchema->GetAttributeProperty(attribute_handle, "xpath", xpath); AnsiString lookup_fieldname; AnsiString display_fieldname; if (nested_subscript == 0) { lookup_fieldname.sprintf("$%s", fieldname.c_str()); display_fieldname = fieldname.c_str(); } else { lookup_fieldname.sprintf("$%s#%d", fieldname.c_str(), nested_subscript); display_fieldname.sprintf("%s#%d", fieldname.c_str(), nested_subscript); } AnsiString field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, lookup_fieldname.c_str(), udtype, udsubtype); AnsiString key; if (nested_subscript == 0) { key.sprintf("%d_%d_%s", testscenario_no, txnspec_no, fieldname.c_str()); } else { key.sprintf("%d_%d_%s#%d", testscenario_no, txnspec_no, fieldname.c_str(), nested_subscript); } FoundTxnSpecValuePair foundpair(key, 0); foundTxnSpecValueMap.insert(foundpair); TxnSpecValueIterator txnspec_value_itr = txnSpecValueMap.find(key); TxnSpecValue &existing_value = (*txnspec_value_itr).second; // Either no existing entry OR the current entry is NOT User supplied // (ie. Ignore field values for existing user supplied items) if ( (txnspec_value_itr == txnSpecValueMap.end()) || (existing_value.user_supplied == 'N') ) { if ( (existing_value.fieldtag != atoi(tagvalue.c_str()) || (existing_value.fieldvalue != field_value) || (existing_value.xpath != AnsiString(xpath.c_str()))) ) { // Remove the existing value if (txnspec_value_itr != txnSpecValueMap.end()) { sql_statement=""; sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES WHERE " "TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d AND FIELDNAME='%s'", testscenario_no, txnspec_no, fieldname.c_str() ); query->SQL->Text = sql_statement; query->ExecSQL(); } // Add the new value sql_statement=""; if (field_value.Length() > 0) { sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, FIELDVALUE, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, XPATH, SUBSCRIPT, USER_SUPPLIED) " "VALUES (%s,'%s',%d,%d,'%s','%s','%s',%d,'N')", tagvalue.c_str(), field_value.c_str(), testscenario_no, txnspec_no, fieldname.c_str(), display_fieldname.c_str(), xpath.c_str(), nested_subscript); } else { sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, XPATH, SUBSCRIPT, USER_SUPPLIED) " "VALUES (%s,%d,%d,'%s','%s','%s',%d,'N')", tagvalue.c_str(), testscenario_no, txnspec_no, fieldname.c_str(), display_fieldname.c_str(), xpath.c_str(), nested_subscript); } query->SQL->Text = sql_statement; query->ExecSQL(); } } } } } else if (elementtype == "repeat") { string refcountfield; string maxOccursStr; string refcountAttribute; XMLSchema->GetAttributeProperty(attribute_handle, "refcountfield", refcountfield); if (!refcountfield.empty()) { string refcountAttribute = structure_handle+"."+refcountfield; XMLSchema->GetAttributeProperty(refcountAttribute, "max", maxOccursStr); } if (maxOccursStr.empty()) { XMLSchema->GetAttributeProperty(attribute_handle, "maxOccurs", maxOccursStr); } int maxOccurs = atoi(maxOccursStr.c_str()); // Limit to 100 elements if (maxOccurs > 100) { maxOccurs = 100; } string repeat_name; XMLSchema->GetAttributeProperty(attribute_handle, "name", repeat_name); XMLSchema->SetAttributeValue(structure_handle, refcountfield, maxOccurs); for (int occurrence=1; occurrence<=maxOccurs; occurrence++) { string repeat_attribute_handle; AnsiString temp; temp.sprintf("%s.%d.%s", attribute_handle.c_str(), occurrence, repeat_name.c_str()); repeat_attribute_handle = temp.c_str(); string repeat_attribute_datatype; XMLSchema->GetAttributeProperty(repeat_attribute_handle, "datatype", repeat_attribute_datatype); if (repeat_attribute_datatype != "Struct") { string fieldname; string xpath; string tagvalue; XMLSchema->GetAttributeProperty(repeat_attribute_handle, "tag", tagvalue); if (tagvalue.length() > 0) { XMLSchema->GetAttributeProperty(repeat_attribute_handle, "name", fieldname); XMLSchema->GetAttributeProperty(repeat_attribute_handle, "xpath", xpath); string lookup_fieldname = "$"+fieldname; AnsiString field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, lookup_fieldname, udtype, udsubtype); AnsiString key; key.sprintf("%d_%d_%s.%d", testscenario_no, txnspec_no, fieldname.c_str(), occurrence); FoundTxnSpecValuePair foundpair(key, 0); foundTxnSpecValueMap.insert(foundpair); TxnSpecValueIterator txnspec_value_itr = txnSpecValueMap.find(key); TxnSpecValue &existing_value = (*txnspec_value_itr).second; // Either no existing entry OR the current entry is NOT User supplied // (ie. Ignore field values for existing user supplied items) if ( (txnspec_value_itr == txnSpecValueMap.end()) || (existing_value.user_supplied == 'N') ) { if ( (existing_value.fieldtag != atoi(tagvalue.c_str()) || (existing_value.fieldvalue != field_value) || (existing_value.xpath != AnsiString(xpath.c_str()))) ) { // Remove the existing value if (txnspec_value_itr != txnSpecValueMap.end()) { sql_statement=""; sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES WHERE " "TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d AND FIELDNAME='%s' AND SUBSCRIPT=%d", testscenario_no, txnspec_no, fieldname.c_str(), occurrence ); query->SQL->Text = sql_statement; query->ExecSQL(); } AnsiString subscripted_fieldname; subscripted_fieldname.sprintf("%s#%d", fieldname.c_str(), occurrence); // Add the new value sql_statement=""; if (field_value.Length() > 0) { sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, FIELDVALUE, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, SUBSCRIPT, XPATH, USER_SUPPLIED) " "VALUES (%s,'%s',%d,%d,'%s','%s',%d,'%s','N')", tagvalue.c_str(), field_value.c_str(), testscenario_no, txnspec_no, fieldname.c_str(), subscripted_fieldname.c_str(), occurrence, xpath.c_str()); } else { sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, SUBSCRIPT, XPATH, USER_SUPPLIED) " "VALUES (%s,%d,%d,'%s','%s',%d,'%s','N')", tagvalue.c_str(), testscenario_no, txnspec_no, fieldname.c_str(), subscripted_fieldname.c_str(), occurrence, xpath.c_str()); } query->SQL->Text = sql_statement; query->ExecSQL(); } } } // if (tagvalue.length() > 0) } // if (repeat_attribute_datatype != "Struct") else { ProcessTxnStructure(repeat_attribute_handle, udtype, udsubtype, testscenario_no, txnspec_no, query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, occurrence); } } // for (int i=1; i<=occurrence; i++) } s_itr++; } // while } //--------------------------------------------------------------------------- AnsiString TMainForm::LookupParameter(IterationParams &iteration_params, IterationSequences &iteration_sequences, TADOQuery *query, int testscenario_no, const string ¶m, unsigned short udtype, unsigned short udsubtype) { AnsiString field_value; AnsiString param_lookup; param_lookup.sprintf("#%d_%s", testscenario_no, param.c_str()); IterationParams::iterator param_itr = iteration_params.find(param_lookup.c_str()); if (param_itr == iteration_params.end()) { param_lookup=""; param_lookup.sprintf("#%d_%s", 0, param.c_str()); param_itr = iteration_params.find(param_lookup.c_str()); } if (param_itr != iteration_params.end()) { string param_value = (*param_itr).second; if (param_value == "@FORMATVERSION") { field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, param_value, udtype, udsubtype); } else if (param_value == "@NOW") { TDateTime current_time = TDateTime::CurrentDateTime(); field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy hh:nn:ss").c_str()); } else if (param_value == "@UTCNOW") { TDateTime current_time = TDateTime::CurrentDateTime() + ((_timezone/3600.0)/24.0); field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy hh:nn:ss").c_str()); } else if (param_value == "@TODAY") { TDateTime current_time = TDateTime::CurrentDateTime(); field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy").c_str()); } else if (param_value == "@YESTERDAY") { TDateTime current_time = TDateTime::CurrentDateTime() - 1; field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy").c_str()); } else if (param_value.substr(0,5) == "@RAND") { int lpos = param_value.find("(")+1; string rand_args = param_value.substr(lpos, param_value.rfind(")")-1); string lower_bound; string upper_bound; const char *p = rand_args.c_str(); while ( (*p != '\0') && (*p != ',') ) { lower_bound += *p; p++; } if ( *p == ',' ) { p++; } while ( (*p != '\0') && (*p != ')') ) { upper_bound += *p; p++; } int lower_int = atoi(lower_bound.c_str()); int upper_int = atoi(upper_bound.c_str()); double rand_key = (double)rand() / (double)RAND_MAX; int rand_value = (rand_key * (upper_int - lower_int)) + lower_int; field_value.sprintf("%d", rand_value); } else if (param_value == "@UDTYPE") { field_value.sprintf("%d", udtype); } else if (param_value == "@UDSUBTYPE") { field_value.sprintf("%d", udsubtype); } else if (param_value == "@ACCOUNTTYPE") { int account_format = 0; switch(udtype) { case 1: // Card account_format = 2; break; case 2: // Application account_format = 1; break; case 3: // Product account_format = 3; break; case 4: // Other account_format = 4; break; case 5: // Audit account_format = 4; break; case 6: // Event account_format = 4; break; case 7: // Project account_format = 4; break; } // switch field_value.sprintf("%d", account_format); } else if (param_value.substr(0,4) == "@SEQ") { int lpos = param_value.find("(")+1; int comma_pos = param_value.find(","); string seqname = param_value.substr( lpos, comma_pos-lpos ); IterationSequences::iterator s_itr = iteration_sequences.find( seqname ); if (s_itr != iteration_sequences.end()) { IterationSequence &sequence = (*s_itr).second; field_value.sprintf("%d", sequence.value); sequence.value += sequence.increment; if (sequence.reset_at != 0) { if (sequence.value >= sequence.reset_at) { sequence.value = sequence.initial_value; } } if (seqname[0] == '#') { AnsiString sql_statement; string seqgenname = seqname.substr(1,seqname.length()-1); sql_statement.sprintf("UPDATE SEQGEN SET SEQVALUE=%d where PROJECT_CODE='%s' AND ITERATION=%d AND SEQNAME='%s'", sequence.value, m_currentproject.c_str(), m_currentiteration, seqgenname.c_str() ); query->SQL->Text = sql_statement; query->ExecSQL(); } } } else if (param_value[0] == '@') { field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, param_value, udtype, udsubtype); } else { field_value.sprintf("%s", param_value.c_str()); } } return field_value; } //--------------------------------------------------------------------------- void __fastcall TMainForm::ImportTestDirectorClick(TObject *Sender) { TestDirectorImportForm->ShowForm( m_currentproject.c_str(), m_currentiteration ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TxnHdrValuesQueryAfterInsert(TDataSet *DataSet) { DataSet->FieldByName("PROJECT_CODE")->AsString = m_currentproject; DataSet->FieldByName("ITERATION")->AsInteger = m_currentiteration; } //--------------------------------------------------------------------------- void __fastcall TMainForm::ScenarioParametersClick(TObject *Sender) { ScenarioParamsForm->ShowForm(m_currentproject, m_currentiteration, m_testscenario_no); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { if (Button == mbRight) { TTreeNode* target_node = TestCaseTreeView->GetNodeAt(X, Y); if (target_node != NULL) { target_node->Selected = true; } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TxnValuesQueryBeforePost(TDataSet *DataSet) { // DataSet->FieldByName( "USER_SUPPLIED" )->AsString = "Y"; } //--------------------------------------------------------------------------- void __fastcall TMainForm::RemoveUserSuppliedValueClick(TObject *Sender) { if (TxnValuesQuery->FieldByName("USER_SUPPLIED")->AsString == "Y") { Data_Module->IntegrationDBConnection->BeginTrans(); TxnValuesQuery->Delete(); Data_Module->IntegrationDBConnection->CommitTrans(); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::CopyValuesToClipboardBtnClick(TObject *Sender) { AnsiString clipboard_text; Clipboard()->Clear(); AnsiString sql_statement; TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; sql_statement.sprintf("SELECT * FROM TXNSPEC_VALUES " "WHERE TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d " "AND (FIELDVALUE IS NOT NULL OR FIELDVALUE<>'') " "ORDER BY FIELDNAME", m_testscenario_no, m_txnspec_no); query->SQL->Text = sql_statement; query->Open(); while (!query->Eof) { AnsiString clipboard_line; clipboard_line.sprintf("%-30.30s\t%s\r\n", query->FieldByName("FIELDNAME")->AsString.c_str(), query->FieldByName("FIELDVALUE")->AsString.c_str() ); clipboard_text += clipboard_line; query->Next(); } query->Close(); Clipboard()->SetTextBuf( clipboard_text.c_str() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildExecutionSchedule( TransactionSpecification & transactionSpecification ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "XPATH," "FIELDVALUE " "FROM " "TXNSPEC_VALUES " "WHERE " "TXNSPEC_NO=%d AND " "FIELDVALUE IS NOT NULL AND " "OBSOLETE=\'N\' " "ORDER BY " "ORDINAL", transactionSpecification.getTransactionSpecificationNumber() ); query->SQL->Text = sqlStatement; query->Open(); TransactionSpecificationValue * value = 0; while ( !query->Eof ) { value = &transactionSpecification.getTransactionField( query->FieldByName( "XPATH" )->AsString.c_str() ); value->setExpression( query->FieldByName( "FIELDVALUE" )->AsString.c_str() ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildExecutionSchedule( TestScenario & testScenario ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TRANSACTION_SPECIFICATION.TXNSPEC_NO AS TXNSPEC_NO," "TRANSACTION_SPECIFICATION.UDTYPE AS UDTYPE," "TRANSACTION_SPECIFICATION.UDSUBTYPE AS UDSUBTYPE," "MASS_TXNS.NAME AS NAME " "FROM " "TRANSACTION_SPECIFICATION," "MASS_TXNS " "WHERE " "TESTSCENARIO_NO=%d AND " "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND " "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND " "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND " "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE " "ORDER BY " "SEQ_NO", testScenario.getScenarioNumber() ); query->SQL->Text = sqlStatement; query->Open(); TransactionSpecification * transaction = 0; while ( !query->Eof ) { transaction = &testScenario.getTransactionSpecification( query->FieldByName( "TXNSPEC_NO" )->AsInteger, query->FieldByName( "NAME" )->AsString.c_str() ); transaction->setUdType( query->FieldByName( "UDTYPE" )->AsInteger ); transaction->setUdSubtype( query->FieldByName( "UDSUBTYPE" )->AsInteger ); buildExecutionSchedule( *transaction ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::buildExecutionSchedule( Iteration & iteration, const std::string & testcaseId ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TESTSCENARIO_NO," "REPEAT_COUNT," "BATCH_SIZE," "NAME " "FROM " "TEST_SCENARIOS " "WHERE " "TESTCASE_ID=\'%s\' AND " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d " "ORDER BY " "TESTCASE_SEQNO", Utilities::EscapeString( testcaseId ).c_str(), Utilities::EscapeString( iteration.getProjectCode() ).c_str(), iteration.getIterationId() ); query->SQL->Text = sqlStatement; query->Open(); TestScenario * scenario = 0; while ( !query->Eof ) { scenario = &iteration.getTestScenario( query->FieldByName( "TESTSCENARIO_NO" )->AsInteger ); scenario->setBatchSize( !query->FieldByName( "BATCH_SIZE" )->IsNull ? query->FieldByName( "BATCH_SIZE" )->AsInteger : 0 ); scenario->setRepeatCount( !query->FieldByName( "REPEAT_COUNT" )->IsNull ? query->FieldByName( "REPEAT_COUNT" )->AsInteger : 1 ); scenario->setScenarioName( query->FieldByName( "NAME" )->AsString.c_str() ); buildExecutionSchedule( *scenario ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::loadLegacyVariables( DefinedVariableTable & variables, const AnsiString & project, Iteration & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "NAME," "FIELDVALUE," "TESTSCENARIO_NO " "FROM " "ITERATION_PARAMS " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", project.c_str(), iteration.getIterationId() ); query->SQL->Text = sqlStatement; query->Open(); AnsiString fieldName; AnsiString xpath; AnsiString value; bool qualified; DefinedVariable * variable; while ( !query->Eof ) { fieldName = query->FieldByName( "NAME" )->AsString; value = query->FieldByName( "FIELDVALUE" )->AsString; if ( !value.IsEmpty() ) { if ( value[ 1 ] == '=' ) { value.Delete( 1, 1 ); } if ( !value.IsEmpty() ) { switch ( value[ 1 ] ) { case '@': value[ 1 ] = '='; if ( FieldExpression::isFunctor( value.c_str() + 1 ) ) { value += "()"; } break; default: break; } } } if ( !fieldName.IsEmpty() ) { qualified = !query->FieldByName( "TESTSCENARIO_NO" )->IsNull; switch ( fieldName[ 1 ] ) { case '$': // We don't worry about fields here. break; case '@': if ( qualified ) { variable = &variables.defineVariable( fieldName.c_str() + 1, iteration.getTestScenario( query->FieldByName( "TESTSCENARIO_NO" ) ->AsInteger ) ); } else { variable = &variables.defineVariable( fieldName.c_str() + 1 ); } variable->setExpression( value.c_str() ); break; default: break; } } query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::readSequences( SequenceCollection & sequences, const std::string & project, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "SEQNAME," "SEQVALUE " "FROM " "SEQGEN " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", Utilities::EscapeString( project ).c_str(), iteration ); query->SQL->Text = sqlStatement; query->Open(); std::string sequenceName; int value; Sequence * sequence; while ( !query->Eof ) { sequenceName = query->FieldByName( "SEQNAME" )->AsString.c_str(); value = query->FieldByName( "SEQVALUE" )->AsInteger; sequence = &sequences.getSequence( sequenceName, true, 0 ); sequence->setValue( value ); sequence->setUpdate( true ); sequence->setDirty( false ); query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::writeSequences( const SequenceCollection & sequences, const std::string & project, const int & iteration ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; for ( std::map< std::string, Sequence * >::const_iterator sequence = sequences.getCollection().begin(); sequence != sequences.getCollection().end(); ++sequence ) { std::stringstream stream; if ( sequence->second->isPersisted() && sequence->second->isDirty() ) { if ( sequence->second->isUpdate() ) { stream << "UPDATE SEQGEN SET " << "SEQVALUE=" << sequence->second->getValue() << " WHERE " << "PROJECT_CODE=\'" << Utilities::EscapeString( project ) << "\' AND " << "ITERATION=" << iteration << " AND " << "SEQNAME=\'" << Utilities::EscapeString( sequence->second->getName() ) << '\''; } else { stream << "INSERT INTO SEQGEN ( " "PROJECT_CODE," "ITERATION," "SEQNAME," "SEQVALUE " " ) VALUES ( " << '\'' << Utilities::EscapeString( project ) << "\'," << iteration << ",\'" << Utilities::EscapeString( sequence->second->getName() ) << "\'," << sequence->second->getValue() << " )"; } query->SQL->Text = stream.str().c_str(); if ( query->ExecSQL() != 1 ) { MTHROW( std::runtime_error, \ "Cannot " \ << ( sequence->second->isUpdate() ? "update" : "insert" ) \ << " sequence \"" \ << sequence->second->getName() \ << "\"." ); } } } SequenceGeneratorQuery->Refresh(); } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::GenerateTestTestCaseBtnClick(TObject *Sender) { std::vector< int > scenarios; generateTransaction( scenarios ); } //--------------------------------------------------------------------------- const unsigned __fastcall TMainForm::countTransactionsInIteration( const char * project, const int & iteration ) { unsigned count = 0; TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "COUNT(*) AS COUNT " "FROM " "TRANSACTION_SPECIFICATION " "WHERE " "PROJECT_CODE=\'%s\' AND " "ITERATION=%d", project, iteration ); query->SQL->Text = sqlStatement; query->Open(); count = ( !query->Eof ? query->FieldByName( "COUNT" )->AsInteger : 0 ); } __finally { delete query; query = 0; } return ( count ); } //--------------------------------------------------------------------------- const unsigned __fastcall TMainForm::countTransactionsInScenario( const int & scenario ) { unsigned count = 0; TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "COUNT(*) AS COUNT " "FROM " "TRANSACTION_SPECIFICATION " "WHERE " "TESTSCENARIO_NO=%d", scenario ); query->SQL->Text = sqlStatement; query->Open(); count = ( !query->Eof ? query->FieldByName( "COUNT" )->AsInteger : 0 ); } __finally { delete query; query = 0; } return ( count ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::applyTemplatesToTransaction( ProgressBar & progressBar, const int & transaction, const TestScenarioTemplate * testScenario, const TestScenarioTemplate * all ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "XPATH," "FIELDVALUE " "FROM " "TXNSPEC_VALUES " "WHERE " "TXNSPEC_NO=%d AND " "USER_SUPPLIED=\'N\' AND " "CHILD_COUNT=0", transaction ); query->SQL->Text = sqlStatement; query->Open(); std::string xpath; std::string value; unsigned matchCount = 0; AnsiString fieldValue; while ( !query->Eof ) { xpath = query->FieldByName( "XPATH" )->AsString.c_str(); fieldValue = query->FieldByName( "FIELDVALUE" )->AsString; matchCount = ( testScenario ? testScenario->findMatch( value, xpath ) : 0 ); if ( matchCount == 1 ) { query->Edit(); query->FieldByName( "FIELDVALUE" )->AsString = value.c_str(); query->Post(); } else if ( matchCount > 1 ) { MTHROW( std::runtime_error, \ "Ambigious scenario transaction template. " \ << matchCount \ << " matches found for \"" \ << xpath \ << "\"." ); } else { matchCount = ( all ? all->findMatch( value, xpath ) : 0 ); if ( matchCount == 1 ) { query->Edit(); query->FieldByName( "FIELDVALUE" )->AsString = value.c_str(); query->Post(); } else if ( matchCount > 1 ) { MTHROW( std::runtime_error, \ "Ambigious transaction template. " \ << matchCount \ << " matches found for \"" \ << xpath \ << "\"." ); } } query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::applyTemplatesToScenario( ProgressBar & progressBar, const int & scenario ) { /** * Iterate through the collection of transactions defined for this scenario * and for each field attempt to apply every field template defined. When * multiple fields match, raise an exception and roll any template * applications back. */ TestScenarioTemplate * testScenario = m_transactionTemplates.findTestScenarioTemplate( scenario ); TestScenarioTemplate * all = m_transactionTemplates.findTestScenarioTemplate( 0 ); if ( testScenario || all ) { TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sqlStatement; sqlStatement.sprintf( "SELECT " "TXNSPEC_NO," "NAME " "FROM " "TRANSACTION_SPECIFICATION," "MASS_TXNS " "WHERE " "TESTSCENARIO_NO=%d AND " "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND " "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND " "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND " "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE " "ORDER BY " "TESTSCENARIO_NO," "TXNSPEC_NO", scenario ); query->SQL->Text = sqlStatement; query->Open(); AnsiString message; while ( !query->Eof ) { message.sprintf( " Applying template to %s ...", query->FieldByName( "NAME" )->AsString.c_str() ); MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message; Application->ProcessMessages(); applyTemplatesToTransaction( progressBar, query->FieldByName( "TXNSPEC_NO" )->AsInteger, testScenario, all ); progressBar.increment(); query->Next(); } } __finally { delete query; query = 0; MainStatusBar->Panels->Items[ g_messagePanel ]->Text = ""; } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ApplyTemplatesToScenarioClick(TObject *Sender) { // The scenario, our context, is kept in the tag of our parent menu. TPopupMenu * menu = dynamic_cast< TPopupMenu * >( dynamic_cast< TMenuItem * >( Sender )->GetParentMenu() ); if ( menu ) { const int scenario = menu->Tag; try { const TCursor Save_Cursor = Screen->Cursor; try { Screen->Cursor = crHourGlass; const unsigned count = countTransactionsInScenario( scenario ); m_progressBar->open( count * 2 ); buildTransactionsForScenario( m_transactionCache, *m_progressBar, scenario, m_schema_handle, m_currentiteration ); try { Data_Module->IntegrationDBConnection->BeginTrans(); applyTemplatesToScenario( *m_progressBar, scenario ); Data_Module->IntegrationDBConnection->CommitTrans(); } catch ( ... ) { Data_Module->IntegrationDBConnection->RollbackTrans(); throw; } m_progressBar->update( count ); } __finally { m_progressBar->close(); Screen->Cursor = Save_Cursor; } } catch ( const std::exception & exception ) { MessageDlg( exception.what(), mtError, TMsgDlgButtons() << mbOK, 0 ); } catch ( ... ) { MessageDlg( "Unknown exception applying templates to this scenario.", mtError, TMsgDlgButtons() << mbOK, 0 ); } } } //--------------------------------------------------------------------------- string __fastcall TMainForm::FindField(const string &structure_handle, int fieldtag) { string field_path; vector structure_attributes; vector::iterator s_itr; XMLSchema->GetAttributes(structure_handle, structure_attributes); s_itr = structure_attributes.begin(); while (s_itr != structure_attributes.end()) { string elementtype; string datatype; XMLSchema->GetAttributeProperty((*s_itr), "type", elementtype); if (elementtype == "field") { XMLSchema->GetAttributeProperty((*s_itr), "datatype", datatype); if (datatype == "Struct") { field_path = FindField((*s_itr), fieldtag); if (!field_path.empty()) { break; } } else { string xml_fieldtag; XMLSchema->GetAttributeProperty((*s_itr), "tag", xml_fieldtag); if ( fieldtag == atoi(xml_fieldtag.c_str()) ) { field_path = (*s_itr); break; } } } else if (elementtype == "repeat") { string repeatname; XMLSchema->GetAttributeProperty((*s_itr), "name", repeatname); string repeatAttribute = (*s_itr)+".1"; field_path = FindField(repeatAttribute, fieldtag); if (!field_path.empty()) { break; } } s_itr++; } return field_path; } void __fastcall TMainForm::FieldEnumValuesDblClick(TObject *Sender) { TADOQuery * query = 0; if ( TransactionStructurePageControl->ActivePage == PayloadStructureTabSheet ) { query = TxnValuesQuery; } else if ( TransactionStructurePageControl->ActivePage == HeaderStructureTabSheet ) { query = TxnHeaderValuesQuery; } else if ( TransactionStructurePageControl->ActivePage == ObsoleteFieldTabSheet ) { query = TxnObsoleteValuesQuery; } if ( query ) { if ( query->State != dsEdit ) { query->Edit(); } query->FieldByName( "FIELDVALUE" )->AsString = FieldEnumValues->Items->Strings[ FieldEnumValues->ItemIndex ]; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action) { XMLSchema->Active = false; m_Registry->CloseKey(); delete m_Registry; } //--------------------------------------------------------------------------- void __fastcall TMainForm::SetGenerationDirectoryClick(TObject *Sender) { AnsiString directory; if ( SelectDirectory("Select Generation Directory", "c:\\", directory) ) { if (m_Registry != NULL) { m_Registry->WriteString("MRUGenerationDir", directory); } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseGridRowChanging(TObject *Sender, int OldRow, int NewRow, bool &Allow) { TCursor Save_Cursor = Screen->Cursor; Screen->Cursor = crHourGlass; // Show hourglass cursor try { TestCasesTabSheet->TabVisible = true; MainPageControl->ActivePage = TestCasesTabSheet; TestScenariosTabSheet->TabVisible = false; if ( (m_currentproject.Length() > 0) && (m_currentiteration != 0) ) { TestCaseTreeView->Items->BeginUpdate(); TestCaseTreeView->Items->Clear(); AnsiString sql_statement; TADOQuery *query = new TADOQuery(this); query->Connection = Data_Module->IntegrationDBConnection; AnsiString testcase_id = TestCaseQuery->FieldByName("TESTCASE_ID")->AsString; sql_statement.sprintf("SELECT * FROM TEST_SCENARIOS " "WHERE PROJECT_CODE='%s' AND ITERATION=%d " "AND TESTCASE_ID='%s' " "ORDER BY TESTCASE_SEQNO", m_currentproject.c_str(), m_currentiteration, testcase_id.c_str()); query->SQL->Text = sql_statement; query->Open(); int count = 0; while (!query->Eof) { AnsiString testcase_desc; testcase_desc.sprintf("(%d) %s", query->FieldByName("TESTCASE_SEQNO")->AsInteger, query->FieldByName("NAME")->AsString.c_str() ); int testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger; TTreeNode *testcase_node = TestCaseTreeView->Items->AddObject(NULL, testcase_desc, (void *)testscenario_no); LoadTestCaseNodes(testcase_node); ++count; query->Next(); } GenerateTestTestCaseBtn->Enabled = ( count > 0 ); delete query; TestCaseTreeView->Items->EndUpdate(); } } __finally { Screen->Cursor = Save_Cursor; } Allow = true; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseQueryAfterClose(TDataSet *DataSet) { TestScenarioToolBar->Enabled = false; AddTestCaseNode->Enabled = false; // InitTxnBtn->Enabled = false; // GenerateAllTxnsBtn->Enabled = false; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseQueryAfterOpen(TDataSet *DataSet) { TestScenarioToolBar->Enabled = true; AddTestCaseNode->Enabled = true; // InitTxnBtn->Enabled = true; // GenerateAllTxnsBtn->Enabled = true; } //--------------------------------------------------------------------------- void __fastcall TMainForm::SequenceGeneratorQueryAfterInsert( TDataSet *DataSet) { DataSet->FieldByName("PROJECT_CODE")->AsString = m_currentproject; DataSet->FieldByName("ITERATION")->AsInteger = m_currentiteration; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseQueryBeforePost(TDataSet *DataSet) { DataSet->FieldByName("USECASE_ID")->AsString = DataSet->FieldByName("TESTCASE_ID")->AsString; } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewEditing(TObject *Sender, TTreeNode *Node, bool &AllowEdit) { if (Node->Level == 0) { AllowEdit = true; } else { AllowEdit = false; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewEdited(TObject *Sender, TTreeNode *Node, AnsiString &S) { // We've enable editing of the root level only, but we'll check anyway. if (Node->Level == 0) { const int testscenario_no = (int)(Node->Data); TADOQuery * query = 0; try { query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; AnsiString sql_statement; AnsiString name; sql_statement.sprintf( "UPDATE TEST_SCENARIOS SET NAME='%s' WHERE TESTSCENARIO_NO=%d", Utilities::EscapeString( getNameFromNode( name, S ) ).c_str(), testscenario_no ); query->SQL->Text = sql_statement; Data_Module->IntegrationDBConnection->BeginTrans(); try { query->ExecSQL(); Data_Module->IntegrationDBConnection->CommitTrans(); } catch ( ... ) { Data_Module->IntegrationDBConnection->RollbackTrans(); } } __finally { delete query; } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestScenarioPropertiesClick(TObject *Sender) { TestScenarioPropertiesForm->ShowForm( m_testscenario_no ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TestCaseTreeViewContextPopup(TObject *Sender, TPoint &MousePos, bool &Handled) { TTreeView * view = dynamic_cast< TTreeView * >( Sender ); if ( view ) { TTreeNode * Node = view->GetNodeAt( MousePos.x, MousePos.y ); const TPoint screen = TestCaseTreeView->ClientToScreen( MousePos ); if ( Node ) { switch ( Node->Level ) { case 0: // Rebuild the transaction templates, they may have changed. buildTransactionTemplates( m_transactionTemplates, m_currentproject, m_currentiteration ); ApplyTemplatesToScenario->Enabled = ( m_transactionTemplates.haveTemplatesForScenario( reinterpret_cast< int >( Node->Data ) ) ); ScenarioPopupMenu->Tag = reinterpret_cast< int >( Node->Data ); ScenarioPopupMenu->Popup( screen.x, screen.y ); break; case 1: TransactionPopupMenu->Popup( screen.x, screen.y ); break; } } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::DeleteScenarioClick(TObject *Sender) { bool refresh_testcases = false; for ( unsigned selected_item=0; selected_itemSelectionCount; selected_item++ ) { TTreeNode * current_node = TestCaseTreeView->Selections[ selected_item ]; if ( current_node != NULL ) { if (current_node->Level == 0) // Remove Test Scenario { // Confirm deletion AnsiString message; message.sprintf( "Are you sure you want to delete this test scenario?" ); if ( MessageDlg( message, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes ) { int testscenario_no = (int)(current_node->Data); TADOQuery *query = new TADOQuery(this); AnsiString sql_statement; query->Connection = Data_Module->IntegrationDBConnection; try { Data_Module->IntegrationDBConnection->BeginTrans(); sql_statement.sprintf( "DELETE FROM TXNSPEC_VALUES WHERE TESTSCENARIO_NO=%d", testscenario_no ); query->SQL->Text = sql_statement; query->ExecSQL(); sql_statement=""; sql_statement.sprintf( "DELETE FROM TRANSACTION_SPECIFICATION WHERE TESTSCENARIO_NO=%d", testscenario_no ); query->SQL->Text = sql_statement; query->ExecSQL(); sql_statement=""; sql_statement.sprintf( "DELETE FROM ITERATION_PARAMS WHERE TESTSCENARIO_NO=%d", testscenario_no ); query->SQL->Text = sql_statement; query->ExecSQL(); sql_statement=""; sql_statement.sprintf( "DELETE FROM TEST_SCENARIOS WHERE TESTSCENARIO_NO=%d", testscenario_no ); query->SQL->Text = sql_statement; query->ExecSQL(); Data_Module->IntegrationDBConnection->CommitTrans(); refresh_testcases = true; ResequenceTestCases(current_node); } catch(...) { Data_Module->IntegrationDBConnection->RollbackTrans(); } delete query; } } } } if (refresh_testcases) { bool allow; TestCaseGridRowChanging(Sender, 0, 1, allow = true); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::InitialiseTransactionActionExecute(TObject *Sender) { TCursor Save_Cursor = Screen->Cursor; Screen->Cursor = crHourGlass; // Show hourglass cursor try { TTreeNode * current_node = TestCaseTreeView->Selected; if ( current_node != NULL ) { if ( current_node->Level == 1 ) // Initialise Txn { // int testscenario_no = (int)(current_node->Parent->Data); // int txnspec_no = (int)(current_node->Data); // MessageDlg("Not supported yet", mtInformation, TMsgDlgButtons() << mbOK, 0); } } } __finally { Screen->Cursor = Save_Cursor; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::InitialiseCopyParametersTabSheet(TObject *Sender) { TADOQuery * query = 0; AnsiString sqlStatement; AnsiString iteration; try { SourceIterationComboBox->Clear(); query = new TADOQuery( this ); query->Connection = Data_Module->IntegrationDBConnection; sqlStatement.sprintf( "SELECT * FROM ITERATIONS WHERE PROJECT_CODE='%s' ORDER BY ITERATION", m_currentproject.c_str() ); query->SQL->Text = sqlStatement; query->Open(); while ( !query->Eof ) { if ( query->FieldByName( "ITERATION" )->AsInteger != m_currentiteration ) { iteration.sprintf( "%d", query->FieldByName( "ITERATION" )->AsInteger ); SourceIterationComboBox->AddItem( iteration, ( TObject * )( query->FieldByName( "ITERATION" )->AsInteger ) ); } query->Next(); } } __finally { delete query; query = 0; } } //--------------------------------------------------------------------------- void __fastcall TMainForm::CopyClick(TObject *Sender) { /* * Copy the given iteration into this iteration. We do not clear this * iteration first. */ CopyIterationProcedure->Parameters->ParamValues[ "projectCode" ] = m_currentproject; CopyIterationProcedure->Parameters->ParamValues[ "fromIteration" ] = (int)(SourceIterationComboBox->Items->Objects[SourceIterationComboBox->ItemIndex]); CopyIterationProcedure->Parameters->ParamValues[ "toIteration" ] = m_currentiteration; CopyIterationProcedure->ExecProc(); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionValueGrid1BeforeContractNode( TObject *Sender, int ARow, int ARowReal, bool &Allow) { Allow = ( TransactionValueGrid->RealRow <= ARowReal ); } //--------------------------------------------------------------------------- const bool __fastcall TMainForm::isParent( const int & ordinal ) { return ( std::find( m_parents.begin(), m_parents.end(), ordinal ) != m_parents.end() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionValueGridCanEditCell(TObject *Sender, int ARow, int ACol, bool &CanEdit) { #if INCLUDE_PARENTS /** * Use the real row as the ordinal number into the dataset. When the row * has children, it cannot be edited, otherwise it can. */ CanEdit = !isParent( TransactionValueGrid->RealRowIndex( ARow ) ); #endif } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionValueGridGetDisplText( TObject *Sender, int ACol, int ARow, AnsiString &Value) { #if INCLUDE_PARENTS const int row = TransactionValueGrid->RealRowIndex( ARow ); if ( row > 0 ) { switch ( TransactionValueGrid->RealColIndex( ACol ) ) { case 2: // The value column. /** * Use the real row as the ordinal number into the dataset. When * the row has children, it cannot be edited, otherwise it can. */ if ( isParent( row ) ) { Value = "{...}"; } break; case 3: // The checkbox column. if ( isParent( row ) ) { Value = ""; } break; } } #endif } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionGridRowChanging( TADOQuery & query, const char * structureName ) { TxnFieldComments->Lines->Clear(); FieldEnumValues->Clear(); FieldDatatype->Clear(); DocDataType->Clear(); IncludedInMac->Checked = false; if ( query.State != dsInactive && query.RecordCount ) { if (!m_schema_handle.empty()) { const int fieldtag = query.FieldByName("FIELDTAG")->AsInteger; string structure_handle; try { XMLSchema->Create(m_schema_handle.c_str(), structureName, m_currentiteration, structure_handle, NULL); string field_path = FindField(structure_handle, fieldtag); if (!field_path.empty()) { std::string fieldcomments; std::string datatype; std::string docdatatype; std::string includedInMac; XMLSchema->GetAttributeProperty(field_path, "comments", fieldcomments); TxnFieldComments->Lines->Add(fieldcomments.c_str()); XMLSchema->GetAttributeProperty(field_path, "datatype", datatype); FieldDatatype->Text = datatype.c_str(); XMLSchema->GetAttributeProperty(field_path, "docdatatype", docdatatype ); DocDataType->Text = docdatatype.c_str(); XMLSchema->GetAttributeProperty(field_path, "inMac", includedInMac ); IncludedInMac->Checked = ( includedInMac == "true" ); string valuemap; XMLSchema->GetAttributeProperty(field_path, "valuemap", valuemap); if (!valuemap.empty()) { vector enum_values; if (XMLSchema->GetEnumerationValues(m_schema_handle, valuemap.c_str(), enum_values)) { vector::iterator eitr = enum_values.begin(); while (eitr != enum_values.end()) { FieldEnumValues->AddItem( (*eitr).c_str(), NULL); ++eitr; } } } } } __finally { XMLSchema->Destroy( structure_handle ); } } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionValueGridRowChanging(TObject *Sender, int OldRow, int NewRow, bool &Allow) { TransactionGridRowChanging( *TxnValuesQuery, m_structure_name.c_str() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::ObsoleteFieldGridRowChanging(TObject *Sender, int OldRow, int NewRow, bool &Allow) { TransactionGridRowChanging( *TxnObsoleteValuesQuery, m_structure_name.c_str() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::HeaderStructureGridRowChanging(TObject *Sender, int OldRow, int NewRow, bool &Allow) { TransactionGridRowChanging( *TxnHeaderValuesQuery, g_headerStructure ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::HeaderStructureTabSheetShow(TObject *Sender) { TransactionGridRowChanging( *TxnHeaderValuesQuery, g_headerStructure ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::PayloadStructureTabSheetShow(TObject *Sender) { TransactionGridRowChanging( *TxnValuesQuery, m_structure_name.c_str() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::ObsoleteFieldTabSheetShow(TObject *Sender) { TransactionGridRowChanging( *TxnObsoleteValuesQuery, m_structure_name.c_str() ); } //--------------------------------------------------------------------------- void __fastcall TMainForm::MainStatusBarResize(TObject *Sender) { if ( m_progressBar ) { RECT Rect; MainStatusBar->Perform( SB_GETRECT, 0, (LPARAM)&Rect ); const int progressPanel = 1; int offset = 0; for ( int i = 0; i < progressPanel; i++ ) { offset += MainStatusBar->Panels->Items[ i ]->Width; } m_progressBar->resize( Rect.top, Rect.left + offset, MainStatusBar->Panels->Items[ progressPanel ]->Width, Rect.bottom - Rect.top ); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::TransactionValueGridKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == 'F' ) { TShiftState mask; mask << ssCtrl; if ( Shift * mask == mask ) { TransactionValueGridFindDialog->Execute(); } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::HeaderStructureGridKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == 'F' ) { TShiftState mask; mask << ssCtrl; if ( Shift * mask == mask ) { HeaderStructureGridFindDialog->Execute(); } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ObsoleteFieldGridKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { if ( Key == 'F' ) { TShiftState mask; mask << ssCtrl; if ( Shift * mask == mask ) { ObsoleteFieldGridFindDialog->Execute(); } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::ImportTransactionActionExecute(TObject *Sender) { TTreeNode * currentNode = TestCaseTreeView->Selected; if ( currentNode ) { // Are we importing a scenario, or a single transaction? if ( currentNode->Level == 0 ) { const int testScenarioNumber = reinterpret_cast< int >( currentNode->Data ); if ( ImportTransactionParametersForm->ShowModal() == mrOk ) { for ( int i=0; iImportFileListBox->Items->Count; i++ ) { if ( ImportTransactionParametersForm->ImportFileListBox->Selected[ i ] ) { importTransaction( testScenarioNumber, ImportTransactionParametersForm ->ImportProfileComboBox->Text, ImportTransactionParametersForm ->ImportFileListBox->Items->Strings[ i ] ); } } } } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::importTransaction( const int & testScenarioNumber, const AnsiString & profile, const AnsiString & file ) { UdDrainFile drainFile( *XMLSchema->GetSchemaWrapperFactory(), *XMLSchema->GetSchema() ); if ( drainFile.read( profile == "TDS", m_currentiteration, file.c_str() ) ) { const unsigned int count = drainFile.getTransactionCount(); for ( unsigned int transaction=0; transaction<=count; ++transaction ) { // add each transaction to the identified test scenario number. } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::IterationCopyButtonClick(TObject *Sender) { if ( !m_currentproject.IsEmpty() && m_currentiteration ) { CopyIterationForm->ShowForm( m_currentproject, m_currentiteration ); } } //--------------------------------------------------------------------------- void __fastcall TMainForm::generateTransaction( std::vector< int > & scenarios ) { if ( GenerationPropertiesForm->ShowModal() == mrOk ) { const bool generateHeaders = GenerationPropertiesForm->GenerateHeadersCheckBox->Checked; const std::string folder = GenerationPropertiesForm->GenerationFolderDirectoryEdit->Text.c_str(); const std::string batchPrefix = GenerationPropertiesForm->DrainFilePrefixEdit->Text.c_str(); const std::string batchSuffix = GenerationPropertiesForm->DrainFileSuffixEdit->Text.c_str(); const bool buildManifest = GenerationPropertiesForm->BuildManifestCheckBox->Checked; const std::string manifestPrefix = GenerationPropertiesForm->ManifestPrefixEdit->Text.c_str(); const std::string manifestSuffix = GenerationPropertiesForm->ManifestSuffixEdit->Text.c_str(); const std::string securityServer = GenerationPropertiesForm->SecurityServerPipeEdit->Text.c_str(); const unsigned short keyNumber = GenerationPropertiesForm->KeyNumberEdit->Text.ToInt(); const unsigned short keyVersion = GenerationPropertiesForm->KeyVersionEdit->Text.ToInt(); const std::string pathmapTarget = GenerationPropertiesForm->PathmapTargetEdit->Text.c_str(); const int macAlgorithm = GenerationPropertiesForm->MacAlgorithmComboBox->ItemIndex; /** Create a transaction stream into our generation folder, and generate the transactions into it. We need to know whether we have to prepend header (i.e., whether it is a .xdr which has a header, or a .devud which doesn't). */ const TCursor Save_Cursor = Screen->Cursor; bool transactionOpen = false; ICryptographicServerProxy * cryptographicServerProxy = 0; IMessageDigest * messageDigest = 0; IHash * hash = 0; try { if ( m_securityWrapperFactory ) { cryptographicServerProxy = m_securityWrapperFactory ->createCryptographicServerProxy( securityServer.c_str() ); if ( cryptographicServerProxy ) { if ( cryptographicServerProxy->getModuleCount() ) { /** * We don't know which module will be used to compute the * MAC (security doesn't tell us), so until they do we * assume its the first module. */ const unsigned int serialNumber = cryptographicServerProxy->getSerialNumber( 0 ); /** We now need to turn the 4-byte serial number into an 8-byte diversifier. Apparently, we must do this by writing the serial number into the lower 4-bytes in big endian. An API is being added to crypto to do this: until it is there we need to do it ourselves. */ unsigned char buffer[ 8 ]; buffer[ 0 ] = 0; buffer[ 1 ] = 0; buffer[ 2 ] = 0; buffer[ 3 ] = 0; buffer[ 4 ] = ( serialNumber >> 24 ) & 0xFF; buffer[ 5 ] = ( serialNumber >> 16 ) & 0xFF; buffer[ 6 ] = ( serialNumber >> 8 ) & 0xFF; buffer[ 7 ] = ( serialNumber ) & 0xFF; messageDigest = m_securityWrapperFactory ->createMessageDigest( *cryptographicServerProxy, keyNumber, keyVersion, buffer, sizeof( buffer ) ); /** * If we need to compute the MAC by computing the MAC * of the SHA-1 hash, then we create the hash object * here. */ if ( macAlgorithm == 1 ) { hash = m_securityWrapperFactory->createHash(); } } else { MWARNING( "Cryptographic server has no modules." ); } } } Screen->Cursor = crHourGlass; Data_Module->IntegrationDBConnection->BeginTrans(); transactionOpen = true; TransactionStream stream( folder, batchPrefix, batchSuffix, buildManifest, manifestPrefix, manifestSuffix, pathmapTarget ); Iteration iteration( m_currentproject.c_str(), m_currentiteration, *XMLSchema->GetSchemaWrapperFactory(), *XMLSchema->GetSchema(), m_schema_handle ); DefinedVariableTable definedVariableTable; SequenceCollection sequences; TimeEstimate timeEstimate( *MainStatusBar->Panels->Items[ 0 ] ); EvaluationContext context( definedVariableTable, sequences, *m_progressBar, messageDigest, hash, cryptographicServerProxy, timeEstimate ); buildExecutionSchedule( iteration, TestCaseQuery->FieldByName( "TESTCASE_ID" )->AsString.c_str() ); loadLegacyVariables( definedVariableTable, m_currentproject.c_str(), iteration ); readSequences( sequences, m_currentproject.c_str(), m_currentiteration ); try { int count = 0; bool generated = false; if ( scenarios.empty() ) { count = iteration.getTransactionCount(); m_progressBar->open( count ); timeEstimate.start( count ); generated = iteration.generate( stream, generateHeaders, context ); } else { std::vector< int >::const_iterator where = scenarios.begin(); for ( where = scenarios.begin(); where != scenarios.end(); ++where ) { count += iteration. findTestScenario( *where ).getTransactionCount(); } m_progressBar->open( count ); timeEstimate.start( count ); generated = true; for ( where = scenarios.begin(); where != scenarios.end(); ++where ) { if ( !iteration.findTestScenario( *where ).generate( stream, generateHeaders, context ) ) { generated = false; break; } } } if ( generated ) { writeSequences( sequences, m_currentproject.c_str(), m_currentiteration ); Data_Module->IntegrationDBConnection->CommitTrans(); transactionOpen = false; } } __finally { timeEstimate.stop(); m_progressBar->close(); } } __finally { if ( hash ) { m_securityWrapperFactory->destroyHash( *hash ); hash = 0; } if ( messageDigest ) { m_securityWrapperFactory ->destroyMessageDigest( *messageDigest ); messageDigest = 0; } if ( cryptographicServerProxy ) { m_securityWrapperFactory ->destroyCryptographicServerProxy( *cryptographicServerProxy ); cryptographicServerProxy = 0; } if ( transactionOpen ) { Data_Module->IntegrationDBConnection->RollbackTrans(); } Screen->Cursor = Save_Cursor; } } } //--------------------------------------------------------------------------- void __fastcall TMainForm::GenerateActionExecute(TObject *Sender) { TTreeNode * currentNode = 0; std::vector< int > scenarios; for ( unsigned selection=0; selectionSelectionCount; selection++ ) { currentNode = TestCaseTreeView->Selections[ selection ]; if ( currentNode ) { scenarios.push_back( reinterpret_cast< int >( currentNode->Data ) ); } } generateTransaction( scenarios ); } //---------------------------------------------------------------------------