Subversion Repositories DevTools

Rev

Rev 2265 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2263 kivins 1
//---------------------------------------------------------------------------
2
 
3
#pragma warn -com
4
#include <LoggingMacros.h>
5
#pragma warn +com
6
 
7
#include <vcl.h>
8
#pragma hdrstop
9
 
10
#include "time.h"
11
#include "pcreposix.h"
12
 
13
 
14
#include "DataModule.h"
15
#include "DefinedVariable.h"
16
#include "DefinedVariableTable.h"
17
#include "EvaluationContext.h"
18
#include "FieldExpression.h"
19
#include "FileCtrl.hpp"
20
#include "GenerationProperties.h"
21
#include "ICryptographicServerProxy.h"
22
#include "IHash.h"
23
#include "ImportTransactionParameters.h"
24
#include "InitProgress.h"
25
#include "IMessageDigest.h"
26
#include "ISecurityWrapperFactory.h"
27
#include "Iteration.h"
28
#include "IXmlSchemaWrapperElement.h"
29
#include "Login.h"
30
#include "Main.h"
31
#include "ParameterScope.h"
32
#include "Registry.hpp"
33
#include "ScenarioParameters.h"
34
#include "Sequence.h"
35
#include "SequenceCollection.h"
36
#include "TestHosts.h"
37
#include "TestScenario.h"
38
#include "TestScenarioProperties.h"
39
#include "TestScenarioTemplate.h"
40
#include "TimeEstimate.h"
41
#include "TransactionFieldTemplate.h"
42
#include "TransactionConfig.h"
43
#include "TransactionSpecification.h"
44
#include "TransactionSpecificationValue.h"
45
#include "TransactionSpecificationValueKey.h"
46
#include "TransactionStream.h"
47
#include "TransactionTemplateCollection.h"
48
#include "UdDrainFile.h"
49
#include "UdTransferHistory.h"
50
#include "Utilities.h"
51
#include <algorithm>
52
#include <ctype.h>
53
 
54
//---------------------------------------------------------------------------
55
#pragma package(smart_init)
56
#pragma link "Grids_ts"
57
#pragma link "TSDBGrid"
58
#pragma link "TSGrid"
59
#pragma link "TXMLSchema"
60
#pragma link "AdvGrid"
61
#pragma link "BaseGrid"
62
#pragma link "DBAdvGrd"
63
#pragma link "DBAdvNavigator"
64
#pragma link "AdvPageControl"
65
#pragma link "AsgFindDialog"
66
#pragma link "DBAdvGrd"
67
#pragma link "DBAdvGrid"
68
#pragma resource "*.dfm"
69
TMainForm *MainForm;
70
 
71
#define TDBADVGRID_FIXED   0
72
#define INCLUDE_PARENTS    TDBADVGRID_FIXED
73
 
74
const char *TMainForm::g_headerStructure  = "SysHdr_t";
75
const int   TMainForm::g_messagePanel     = 0;
76
 
77
 
78
 
79
/**
80
 * Process paint message.
81
 */
82
void ProcessPaintMessages( HWND Handle )
83
{
84
   MSG msg;
85
   while ( PeekMessage( &msg, Handle, WM_PAINT, WM_PAINT, PM_REMOVE ) )
86
   {
87
      DispatchMessage( &msg );
88
   }
89
}
90
//---------------------------------------------------------------------------
91
 
92
const bool __fastcall TMainForm::openSecurityFactory( const char * library )
93
{
94
 
95
 
96
   //ShellExecute(Handle,"open",PChar("command.com /c"),PChar("C:\\afctxn\\ERGsec\\scripts\\exprc_cryptoserver.bat"),0,SW_NORMAL);
97
   //Sleep(10);
98
 
99
    STARTUPINFO si;
100
    PROCESS_INFORMATION pi;
101
 
102
    memset (&pi, 0, sizeof(pi));
103
    memset (&si, 0, sizeof(si));
104
 
105
    si.cb = sizeof(si);
106
    si.dwFlags |=STARTF_USESHOWWINDOW;
107
    si.wShowWindow|=SW_SHOWNORMAL;
108
 
109
    if ( ! CreateProcess(
110
            "C:\\WINDOWS\\system32\\cmd.exe ",
111
            "/c C:\\afctxn\\ERGsec\\scripts\\exprc_cryptoserver.bat" ,
112
            NULL,
113
            NULL,
114
            false,
115
            NORMAL_PRIORITY_CLASS,
116
            NULL,
117
            NULL,
118
            &si,
119
            &pi))
120
            {
121
            MessageBox(0, "Could not execte program \n Please contact software author.", "Error", MB_ICONSTOP);
122
            }
123
 
124
 
125
   m_securityWrapper = ::LoadLibrary( library );
126
   if ( m_securityWrapper )
127
   {
128
      m_getSecurityWrapperFactory
129
         = reinterpret_cast< getSecurityWrapperFactory_t >(
130
            ::GetProcAddress(
131
               m_securityWrapper,
132
               "getSecurityWrapperFactory" ) );
133
 
134
      if ( m_getSecurityWrapperFactory )
135
      {
136
         m_securityWrapperFactory = &m_getSecurityWrapperFactory();
137
         if ( m_securityWrapperFactory )
138
         {
139
            return ( m_securityWrapperFactory->start() );
140
         }
141
      }
142
   }
143
 
144
   return ( false );
145
}
146
//---------------------------------------------------------------------------
147
 
148
void __fastcall TMainForm::closeSecurityFactory()
149
{
150
   if ( m_securityWrapperFactory )
151
   {
152
      m_securityWrapperFactory->stop();
153
      m_securityWrapperFactory = 0;
154
   }
155
   m_getSecurityWrapperFactory = 0;
156
   if ( m_securityWrapper )
157
   {
158
      ::FreeLibrary( m_securityWrapper );
159
      m_securityWrapper = 0;
160
   }
161
}
162
//---------------------------------------------------------------------------
163
 
164
__fastcall TMainForm::TMainForm(TComponent* Owner)
165
:  TForm(Owner),
166
   m_progressBar( 0 ),
167
   m_securityWrapper( 0 ),
168
   m_getSecurityWrapperFactory( 0 ),
169
   m_securityWrapperFactory( 0 ),
170
    m_transferManager( 0 ),
171
    m_Registry( 0 ),
172
    m_currentiteration (25),
173
    m_currentproject("SLS")
174
{
175
   //TestCasesTabSheet->TabVisible = false;
176
   //TestScenariosTabSheet->TabVisible = false;
177
 
178
   m_Registry = new TRegistry;
179
   m_Registry->RootKey = HKEY_CURRENT_USER;
180
   if (! m_Registry->OpenKey("\\Software\\ERG\\TxnTestManager", true) )
181
   {
182
      m_Registry->CloseKey();
183
      delete m_Registry;
184
      m_Registry = NULL;
185
   }
186
        else
187
        {
188
        // read in project from the registry
189
         if (m_Registry->ValueExists("MRUProjectCode"))
190
        {
191
         m_currentproject = m_Registry->ReadString("MRUProjectCode");
192
        }
193
        // read in iteration from the registry
194
        if (m_Registry->ValueExists("MRUProjectIteration"))
195
      {
196
         m_currentiteration = m_Registry->ReadInteger("MRUProjectIteration");
197
      }  
198
        }
199
   m_progressBar = new ProgressBar( MainStatusBar );
200
 
201
   /* eventually get this from the registry */
202
   m_engineering_mode = true;
203
 
204
   openSecurityFactory();
205
}
206
//---------------------------------------------------------------------------
207
 
208
__fastcall TMainForm::~TMainForm()
209
{
210
   closeSecurityFactory();
211
 
212
   delete m_progressBar;
213
   m_progressBar = 0;
214
 
215
    delete m_transferManager;
216
    m_transferManager = 0;
217
 
218
    delete m_Registry;
219
    m_Registry = 0;
220
}
221
//---------------------------------------------------------------------------
222
 
223
 
224
 
225
void __fastcall TMainForm::FormShow(TObject *Sender)
226
{
227
#ifdef LOGGING_ACTIVE
228
    ProgrammerLogging::start("TxnTestManager.ini");
229
#endif
230
 
231
    bool retryLogin;
232
    do
233
    {
234
        retryLogin = false;
235
 
236
        if (LoginForm->ShowModal() == mrOk)
237
        {
238
            try
239
            {
240
                // Initialise Startup TabSheets
241
                TestsPageControl->ActivePage = TestCaseTabSheet;
242
                TestParametersPageControl->ActivePage = IterationParametersTabSheet;
243
 
244
                // Initialise the Database connection
245
                Data_Module->IntegrationDBConnection->Connected = false;
246
 
247
                AnsiString connectionString;
248
                connectionString.sprintf( "Provider=OraOLEDB.Oracle.1;Data Source=%s", LoginForm->DatabaseEdit->Text );
249
                Data_Module->IntegrationDBConnection->ConnectionString = connectionString;
250
                Data_Module->IntegrationDBConnection->Open(LoginForm->UsernameEdit->Text, LoginForm->PasswordEdit->Text);
251
                if (!Data_Module->IntegrationDBConnection->Connected)                           
252
                {
253
                    MessageDlg("Failed to connect to datasource with specified username and password.",
254
                                mtError, TMsgDlgButtons() << mbOK, 0);
255
                    retryLogin = true;
256
                }
257
                else
258
                {
259
                    // we have a databse connection so use it
260
                    MASSTxnsQuery->Active = false;
261
                    TestCaseQuery->Active = false;
262
                    TxnSpecQuery->Active = false;
263
                    TxnValuesQuery->Active = false;
264
                    TxnHdrValuesQuery->Active = false;
265
                    IterationParamsQuery->Active = false;
266
                    SequenceGeneratorQuery->Active = false;
267
                    // TxnStepsQuery->Active = true;  ?? can't do yet as we don't have a default scenario
268
 
269
                    srand( static_cast< unsigned >( time( 0 ) ) );
270
                    int    first_rand_seed = rand();
271
 
272
                    srand( first_rand_seed << (first_rand_seed & 0x00FF) );
273
                    //              int    first_rand = rand();
274
 
275
                    // Locate the XML SWIS Schema
276
                    XMLSchema->Active = true;
277
                    vector<string>  schemas;
278
                    if (XMLSchema->GetSchemas(schemas))
279
                    {
280
                        vector<string>::iterator   itr = schemas.begin();
281
 
282
                        while (itr != schemas.end())
283
                        {
284
                            AnsiString    xml_schema = (*itr).c_str();
285
 
286
                            if (xml_schema.Pos(MASSUDWriter) == 1)
287
                            {
288
                                m_xml_schemas.push_back(xml_schema.c_str());
289
                            }
290
 
291
                            ++itr;
292
                        }
293
                    }
294
 
295
                    if (m_xml_schemas.size() == 0)
296
                    {
297
                        MessageDlg("Failed to locate any MASS UD Writer XMLs\n"
298
                                   "Check XMLSchema.ini file",
299
                                   mtError, TMsgDlgButtons() << mbOK, 0);
300
                    }
301
 
302
 
303
                    // use the iteration held in the registry to complete the preparation for the form
304
                    LoadIteration(Sender);
305
                    bool allow;
306
                    TestCaseGridRowChanging(Sender, 0, 1, allow = true );
307
                    MASSTxnTabSheet->Visible = false;
308
                    InitialiseUdTransferManager();
309
                }
310
 
311
            }
312
            catch( EOleException & e )
313
            {
314
                AnsiString msg = "Failed to connect to datasource with specified username and password.\n"
315
                    + e.Message + ".";
316
                MessageDlg(msg, mtError, TMsgDlgButtons() << mbOK, 0);
317
                retryLogin = true;
318
            }
319
            catch(...)
320
            {
321
                Close();
322
            }
323
        }
324
        else
325
        {
326
            Close();
327
        }
328
    } while( retryLogin );
329
}
330
 
331
//---------------------------------------------------------------------------
332
 
333
const bool __fastcall TMainForm::findSchema( std::string &     handle,
334
                                  const AnsiString &  projectCode,
335
                                  const int &      iteration )
336
{
337
   std::string project;
338
   std::string majorVersion;
339
 
340
   for ( std::vector< std::string >::const_iterator
341
         where = m_xml_schemas.begin();
342
        where != m_xml_schemas.end();
343
        ++where )
344
   {
345
      if ( XMLSchema->GetAttributeProperty( *where, "project", project ) &&
346
          ( projectCode == AnsiString( project.c_str() ).UpperCase() ) )
347
      {
348
         if ( ( XMLSchema->GetAttributeProperty( *where, "majorversion", majorVersion ) ) &&
349
             ( iteration == atoi( majorVersion.c_str() ) ) )
350
         {
351
            handle = *where;
352
            return ( true );
353
         }
354
      }
355
   }
356
   handle.erase();
357
 
358
   return ( false );
359
}
360
//---------------------------------------------------------------------------
361
 
362
void __fastcall TMainForm::LoadIteration(TObject *Sender)
363
{
364
   AnsiString  sql_statement;
365
 
366
   if (!findSchema( m_schema_handle, m_currentproject.UpperCase(), m_currentiteration ))
367
   {
368
       AnsiString  message;
369
       message.sprintf("Failed to match project %s and iteration %d in schema xml file",
370
                        m_currentproject, m_currentiteration);
371
       MessageDlg(message, mtError, TMsgDlgButtons() << mbOK, 0);
372
   }
373
 
374
   buildTransactionTemplates( m_transactionTemplates, m_currentproject, m_currentiteration );
375
   ApplyTemplates->Enabled = ( m_transactionTemplates.getTemplateCount() > 0 );
376
 
377
   // Load the Project/Iterations MASS Txns
378
   MASSTxnsQuery->Close();
379
   sql_statement="";
380
   sql_statement.sprintf("SELECT * FROM MASS_TXNS WHERE PROJECTCODE='%s' AND ITERATION=%d AND ENABLED = 'Y' ORDER BY NAME,UDTYPE,UDSUBTYPE",
381
                    m_currentproject.c_str(),
382
                    m_currentiteration);
383
   MASSTxnsQuery->SQL->Text = sql_statement;
384
   MASSTxnsQuery->Open();
385
 
386
   InitialiseMASSTxns();
387
 
388
    // Refresh the TestCases
389
   if (TestCaseQuery->Active)
390
   {
391
      TestCaseQuery->Close();
392
   }
393
   TestCaseQuery->Open();
394
 
395
   // Load the Project/Iterations Iteration Parameters
396
   IterationParamsQuery->Close();
397
   sql_statement="";
398
   sql_statement.sprintf("SELECT * FROM ITERATION_PARAMS "
399
                    "WHERE PROJECT_CODE='%s' AND ITERATION=%d"
400
                    "AND TESTSCENARIO_NO IS NULL AND SUPPORTED <> 0"
401
                    "ORDER BY NAME",
402
                    m_currentproject.c_str(),
403
                    m_currentiteration);
404
   IterationParamsQuery->SQL->Text = sql_statement;
405
   IterationParamsQuery->Open();
406
 
407
   SequenceGeneratorQuery->Close();
408
   sql_statement="";
409
   sql_statement.sprintf("SELECT * FROM SEQGEN "
410
                    "WHERE PROJECT_CODE='%s' AND ITERATION=%d"
411
                    "ORDER BY SEQNAME",
412
                    m_currentproject.c_str(),
413
                    m_currentiteration);
414
   SequenceGeneratorQuery->SQL->Text = sql_statement;
415
   SequenceGeneratorQuery->Open();
416
 
417
 
418
    // Load the Project/Iterations TXNHDR Parameters
419
    TxnHdrValuesQuery->Close();
420
    sql_statement="";
421
    sql_statement.sprintf("SELECT * FROM TXNHDR_VALUES "
422
                    "WHERE PROJECT_CODE='%s' AND ITERATION=%d",
423
                    m_currentproject.c_str(),
424
                    m_currentiteration);
425
   TxnHdrValuesQuery->SQL->Text = sql_statement;
426
   TxnHdrValuesQuery->Open();
427
}
428
//---------------------------------------------------------------------------
429
 
430
void __fastcall TMainForm::LoadTestCaseNodes(TTreeNode *testcase_node)
431
{
432
   bool  initially_expanded = testcase_node->Expanded;
433
 
434
    TestCaseTreeView->Items->BeginUpdate();
435
 
436
   testcase_node->DeleteChildren();
437
 
438
    TADOQuery  *txnquery = new TADOQuery(this);
439
    txnquery->Connection = Data_Module->IntegrationDBConnection;
440
 
441
    AnsiString sql_statement;
442
    sql_statement.sprintf("SELECT MASS_TXNS.NAME,TRANSACTION_SPECIFICATION.TXNSPEC_NO "
443
                          "FROM MASS_TXNS,TRANSACTION_SPECIFICATION "
444
                          "WHERE TRANSACTION_SPECIFICATION.TESTSCENARIO_NO=%d "
445
                          "AND   MASS_TXNS.PROJECTCODE=TRANSACTION_SPECIFICATION.PROJECT_CODE "
446
                          "AND   MASS_TXNS.ITERATION=TRANSACTION_SPECIFICATION.ITERATION "
447
                          "AND   MASS_TXNS.UDTYPE=TRANSACTION_SPECIFICATION.UDTYPE "
448
                          "AND   MASS_TXNS.UDSUBTYPE=TRANSACTION_SPECIFICATION.UDSUBTYPE "
449
                          "ORDER BY TRANSACTION_SPECIFICATION.SEQ_NO",
450
                          (int)testcase_node->Data);
451
    txnquery->SQL->Text = sql_statement;
452
    txnquery->Open();
453
    while (!txnquery->Eof)
454
    {
455
        AnsiString  txnname   = txnquery->FieldByName("NAME")->AsString;
456
        int       txnspec_no  = txnquery->FieldByName("TXNSPEC_NO")->AsInteger;
457
 
458
        TestCaseTreeView->Items->AddChildObject(testcase_node, txnname.c_str(), (TObject *)txnspec_no);
459
 
460
        txnquery->Next();
461
    }
462
 
463
    delete txnquery;
464
 
465
    if (initially_expanded)
466
    {
467
      testcase_node->Expand(true);
468
    }
469
   /*
470
    else
471
    {
472
       testcase_node->Collapse(true);
473
    }
474
         */
475
    TestCaseTreeView->Items->EndUpdate();
476
}
477
//---------------------------------------------------------------------------
478
 
479
void __fastcall TMainForm::InitialiseUdTransferManager()
480
{
481
    if( m_transferManager == 0 )
482
    {
483
        m_transferManager = new UdTransferManager;
484
        if( m_transferManager != 0 )
485
        {
486
            m_transferManager->LoadPendingTasks();
487
            UdTransferHistoryForm->SetTransferManager(m_transferManager);                    
488
        }
489
    }
490
}
491
//---------------------------------------------------------------------------
492
 
493
void __fastcall TMainForm::EditTestCaseExecute(TObject *Sender)
494
{
495
   //
496
 
497
 
498
}
499
//---------------------------------------------------------------------------
500
 
501
void __fastcall TMainForm::TestCaseTreeViewEnter(TObject *Sender)
502
{
503
//   if (!TestScenariosTabSheet->TabVisible)
504
//    {
505
//        TestScenariosTabSheet->TabVisible = true;
506
//        TestCasesTabSheet->TabVisible = false;
507
//    }
508
 
509
 
510
   // MainPageControl->ActivePage = ScenarioStepsTabSheet;
511
 
512
 
513
}
514
//---------------------------------------------------------------------------
515
 
516
void __fastcall TMainForm::TestCaseQueryAfterPost(TDataSet *DataSet)
517
{
518
    if (TestCaseQuery->Active)
519
    {
520
      TestCaseQuery->Close();
521
    }
522
 
523
    TestCaseQuery->Open();
524
}
525
//---------------------------------------------------------------------------
526
 
527
void __fastcall TMainForm::TxnStepsQueryAfterPost(TDataSet *DataSet)
528
{
529
 
530
 /* This routine was added to copy the exisiting TestCaseQuery behaviour but I am not sure if it is needed. */
531
   if (TxnStepsQuery->Active)
532
    {
533
      TxnStepsQuery->Close();
534
    }
535
 
536
    TxnStepsQuery->Open();
537
//    TxnStepsQuery->Edit();
538
 
539
         MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "posting txn steps";
540
                  Application->ProcessMessages();          
541
}
542
//---------------------------------------------------------------------------
543
 
544
void __fastcall TMainForm::TxnStepsNewRow(TDataSet *DataSet)
545
{
546
    AnsiString message;
547
    message = "Record " + IntToStr(TxnStepsQuery->RecNo) + " of " + IntToStr(TxnStepsQuery->RecordCount);
548
 
549
          MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
550
                  Application->ProcessMessages();
551
 
552
}
553
//---------------------------------------------------------------------------
554
 
555
void __fastcall TMainForm::StepsGridNewRow (TObject *Sender, int ARow)
556
{
557
    AnsiString message;
558
    message = "new grid row at  " + IntToStr(ARow);
559
 
560
         MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
561
                  Application->ProcessMessages();
562
 
563
 
564
 
565
 
566
}
567
//---------------------------------------------------------------------------
568
 
569
void __fastcall TMainForm::StepsGridRowChanging(TObject *Sender,
570
      int OldRow, int NewRow, bool &Allow)
571
{
572
    AnsiString message;
573
    message = "chnaged grid row at  " + IntToStr(NewRow);
574
 
575
         MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
576
                  Application->ProcessMessages();
577
 //Application->MessageBox(message.c_str(),"hello box",NULL);
578
 
579
    //TestCaseGridRowChanging(Sender, 0, 1, Allow);
580
 
581
}
582
//---------------------------------------------------------------------------
583
 
584
void __fastcall TMainForm::loadLegacyHeaderValues( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration )
585
{
586
   TADOQuery * query = 0;
587
   try
588
   {
589
      query = new TADOQuery( this );
590
      query->Connection = Data_Module->IntegrationDBConnection;
591
 
592
      AnsiString sqlStatement;
593
      sqlStatement.sprintf(
594
         "SELECT "
595
            "FIELDNAME,"
596
            "FIELDVALUE "
597
         "FROM "
598
            "TXNHDR_VALUES "
599
         "WHERE "
600
            "PROJECT_CODE=\'%s\' AND "
601
            "ITERATION=%d",
602
         project.c_str(),
603
         iteration );
604
      query->SQL->Text = sqlStatement;
605
      query->Open();
606
 
607
      AnsiString xpath;
608
      AnsiString value;
609
      while ( !query->Eof )
610
      {
611
         value = query->FieldByName( "FIELDVALUE" )->AsString;
612
         if ( !value.IsEmpty() )
613
         {
614
            if ( value[ 1 ] == '=' )
615
            {
616
               value.Delete( 1, 1 );
617
            }
618
 
619
            if ( !value.IsEmpty() )
620
            {
621
               switch ( value[ 1 ] )
622
               {
623
                  case '@':
624
                     value[ 1 ] = '=';
625
                     if ( FieldExpression::isFunctor(
626
                           value.c_str() + 1 ) )
627
                     {
628
                        value += "()";
629
                     }
630
                     break;
631
                  default:
632
                     break;
633
               }
634
            }
635
         }
636
 
637
         xpath.sprintf(
638
            "/%s/%s",
639
            g_headerStructure,
640
            query->FieldByName( "FIELDNAME" )->AsString.c_str() );
641
         templates.getTestScenario( 0 ).getField( xpath.c_str() ).
642
            setValue( value.c_str() );
643
         query->Next();
644
      }
645
   }
646
   __finally
647
   {
648
      delete query;
649
      query = 0;
650
   }
651
}
652
//---------------------------------------------------------------------------
653
 
654
void __fastcall TMainForm::loadLegacyParameters( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration )
655
{
656
   TADOQuery * query = 0;
657
   try
658
   {
659
      query = new TADOQuery( this );
660
      query->Connection = Data_Module->IntegrationDBConnection;
661
 
662
      AnsiString sqlStatement;
663
      sqlStatement.sprintf(
664
         "SELECT "
665
            "NAME,"
666
            "FIELDVALUE,"
667
            "TESTSCENARIO_NO "
668
         "FROM "
669
            "ITERATION_PARAMS "
670
         "WHERE "
671
            "PROJECT_CODE=\'%s\' AND "
672
            "ITERATION=%d ",
673
         project.c_str(),
674
         iteration );
675
      query->SQL->Text = sqlStatement;
676
      query->Open();
677
 
678
      AnsiString  fieldName;
679
      int         scenario = 0;
680
      AnsiString xpath;
681
      AnsiString value;
682
      while ( !query->Eof )
683
      {
684
         fieldName = query->FieldByName( "NAME" )->AsString;
685
         scenario = query->FieldByName( "TESTSCENARIO_NO" )->AsInteger;
686
 
687
         value = query->FieldByName( "FIELDVALUE" )->AsString;
688
         if ( !value.IsEmpty() )
689
         {
690
            if ( value[ 1 ] == '=' )
691
            {
692
               value.Delete( 1, 1 );
693
            }
694
 
695
            if ( !value.IsEmpty() )
696
            {
697
               switch ( value[ 1 ] )
698
               {
699
                  case '@':
700
                     value[ 1 ] = '=';
701
                     if ( FieldExpression::isFunctor(
702
                           value.c_str() + 1 ) )
703
                     {
704
                        value += "()";
705
                     }
706
                     break;
707
                  default:
708
                     break;
709
               }
710
            }
711
         }
712
 
713
         if ( !fieldName.IsEmpty() )
714
         {
715
            switch ( fieldName[ 1 ] )
716
            {
717
            case '$':
718
               xpath.sprintf(
719
                  ".*/%s",
720
                  fieldName.c_str() + 1 );
721
 
722
               templates.getTestScenario( scenario ).getField( xpath.c_str() ).
723
                  setValue( value.c_str() );
724
               break;
725
            case '@':   // We don't worry about variables here.
726
               break;
727
            default:
728
               break;
729
            }
730
         }
731
         query->Next();
732
      }
733
   }
734
   __finally
735
   {
736
      delete query;
737
      query = 0;
738
   }
739
}
740
//---------------------------------------------------------------------------
741
 
742
void __fastcall TMainForm::buildTransactionTemplates( TransactionTemplateCollection & templates, const AnsiString & project, const int & iteration )
743
{
744
   templates.clear();
745
   loadLegacyHeaderValues( templates, project, iteration );
746
   loadLegacyParameters( templates, project, iteration );
747
 
748
   // Now apply our current templates, which override the legacy templates.
749
   /* KI note: it seems that the 'legacy' routines are in fact the real thing
750
      and the comment above is no longer appropriate.  Only guessing though at this stage.
751
      If it turns out to be the case then I'll rename the legacy routines accordingly 
752
   */
753
}
754
 
755
//---------------------------------------------------------------------------
756
 
757
void __fastcall TMainForm::UseCaseDBGridEnter(TObject *Sender)
758
{
759
//   TestCasesTabSheet->TabVisible = true;
760
//   ScenarioStepsTabSheet->TabVisible = true;
761
   MainPageControl->ActivePage = ScenarioStepsTabSheet;
762
//   TestScenariosTabSheet->TabVisible = false;
763
//     TestScenariosTabSheet->Enabled = false;
764
}
765
//---------------------------------------------------------------------------
766
 
767
void __fastcall TMainForm::IterationParamsQueryAfterInsert(
768
      TDataSet *DataSet)
769
{
770
   DataSet->FieldByName("PROJECT_CODE")->AsString  = m_currentproject;
771
   DataSet->FieldByName("ITERATION")->AsInteger    = m_currentiteration;
772
}
773
//---------------------------------------------------------------------------
774
 
775
 
776
void __fastcall TMainForm::readTransactionSpecifications(
777
               TransactionSpecification & transaction,
778
               const int &             transactionSpecification )
779
{
780
   TADOQuery * query = 0;
781
   try
782
   {
783
      query = new TADOQuery( this );
784
      query->Connection = Data_Module->IntegrationDBConnection;
785
 
786
      AnsiString sqlStatement;
787
      sqlStatement.sprintf(
788
         "SELECT "
789
            "XPATH,"
790
            "FIELDVALUE,"
791
            "OBSOLETE "
792
         "FROM "
793
            "TXNSPEC_VALUES "
794
         "WHERE "
795
            "TXNSPEC_NO=%d",
796
         transactionSpecification );
797
      query->SQL->Text = sqlStatement;
798
      query->Open();
799
 
800
      while ( !query->Eof )
801
      {
802
         transaction.addValue(
803
            query->FieldByName( "XPATH" )->AsString.c_str(),
804
            query->FieldByName( "FIELDVALUE" )->AsString.c_str(),
805
            query->FieldByName( "OBSOLETE" )->AsBoolean );
806
         query->Next();
807
      }
808
   }
809
   __finally
810
   {
811
      delete query;
812
      query = 0;
813
   }
814
}
815
 
816
//---------------------------------------------------------------------------
817
 
818
void __fastcall TMainForm::buildTransactionsForIteration(
819
               TransactionCache &   transactionCache,
820
               ProgressBar &     progressBar,
821
               const std::string &  schema,
822
               const std::string &  project,       
823
               const int &       iteration )
824
{
825
   TADOQuery * query = 0;
826
   try
827
   {
828
      query = new TADOQuery( this );
829
      query->Connection = Data_Module->IntegrationDBConnection;
830
 
831
      AnsiString sqlStatement;
832
      sqlStatement.sprintf(
833
         "SELECT "
834
            "TXNSPEC_NO,"
835
            "NAME,"
836
            "TESTSCENARIO_NO "
837
         "FROM "
838
            "TRANSACTION_SPECIFICATION,"
839
            "MASS_TXNS "
840
         "WHERE "
841
            "TRANSACTION_SPECIFICATION.PROJECT_CODE=\'%s\' AND "
842
            "TRANSACTION_SPECIFICATION.ITERATION=%d AND "
843
            "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND "
844
            "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND "
845
            "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND "
846
            "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE "
847
         "ORDER BY "
848
            "TESTSCENARIO_NO,"
849
            "TXNSPEC_NO",
850
         project.c_str(),
851
         iteration );
852
      query->SQL->Text = sqlStatement;
853
      query->Open();
854
 
855
      AnsiString xpath;
856
      AnsiString message;
857
      while ( !query->Eof )
858
      {
859
         if ( !m_transactionCache.isContained( query->FieldByName( "TXNSPEC_NO" )->AsInteger ) )
860
         {
861
            message.sprintf(
862
               " Building %s ...",
863
               query->FieldByName( "NAME" )->AsString.c_str() );
864
            MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
865
            Application->ProcessMessages();
866
 
867
            buildTransactionSpecificationValues(
868
               transactionCache,
869
               query->FieldByName( "TESTSCENARIO_NO" )->AsInteger,
870
               query->FieldByName( "TXNSPEC_NO" )->AsInteger,
871
               query->FieldByName( "NAME" )->AsString.c_str(),
872
               g_headerStructure,
873
               schema,
874
               iteration );
875
         }
876
         else
877
         {
878
            message.sprintf(
879
               " Using cached %s ...",
880
               query->FieldByName( "NAME" )->AsString.c_str() );
881
            MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
882
            Application->ProcessMessages();
883
         }
884
 
885
         progressBar.increment();
886
         query->Next();
887
      }
888
   }
889
   __finally
890
   {
891
      delete query;
892
      query = 0;
893
 
894
      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "";
895
   }
896
}
897
//---------------------------------------------------------------------------
898
 
899
void __fastcall TMainForm::buildTransactionsForScenario(
900
               TransactionCache &   transactionCache,
901
               ProgressBar &     progressBar,
902
               const int &       scenario,
903
               const std::string &  schema,
904
               const int &       iteration )
905
{
906
   TADOQuery * query = 0;
907
   try
908
   {
909
      query = new TADOQuery( this );
910
      query->Connection = Data_Module->IntegrationDBConnection;
911
 
912
      AnsiString sqlStatement;
913
      sqlStatement.sprintf(
914
         "SELECT "
915
            "TXNSPEC_NO,"
916
            "NAME "
917
         "FROM "
918
            "TRANSACTION_SPECIFICATION,"
919
            "MASS_TXNS "
920
         "WHERE "
921
            "TRANSACTION_SPECIFICATION.TESTSCENARIO_NO=%d AND "
922
            "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND "
923
            "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND "
924
            "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND "
925
            "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE "
926
         "ORDER BY "
927
            "TXNSPEC_NO",
928
         scenario );
929
      query->SQL->Text = sqlStatement;
930
      query->Open();
931
 
932
      AnsiString xpath;
933
      AnsiString message;
934
      while ( !query->Eof )
935
      {
936
         if ( !m_transactionCache.isContained( query->FieldByName( "TXNSPEC_NO" )->AsInteger ) )
937
         {
938
            message.sprintf(
939
               " Building %s ...",
940
               query->FieldByName( "NAME" )->AsString.c_str() );
941
 
942
            buildTransactionSpecificationValues(
943
               transactionCache,
944
               scenario,
945
               query->FieldByName( "TXNSPEC_NO" )->AsInteger,
946
               query->FieldByName( "NAME" )->AsString.c_str(),
947
               g_headerStructure,
948
               schema,
949
               iteration );
950
         }
951
         else
952
         {
953
            message.sprintf(
954
               " Using cached %s ...",
955
               query->FieldByName( "NAME" )->AsString.c_str() );
956
         }
957
 
958
         MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
959
         Application->ProcessMessages();
960
 
961
         progressBar.increment();
962
         query->Next();
963
      }
964
   }
965
   __finally
966
   {
967
      delete query;
968
      query = 0;
969
 
970
      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "";
971
   }
972
}
973
//---------------------------------------------------------------------------
974
 
975
void __fastcall TMainForm::buildTransactionSpecificationValues(
976
               TransactionCache &   transactionCache,
977
               const int &       testScenario,
978
               const int &       transactionSpecification,
979
               const std::string &  transactionStructureName,
980
               const std::string &  headerStructureName,
981
               const std::string &  schema,
982
               const int &       iteration )
983
{
984
   /**
985
    * Ensure that for each transactionSpecification and iteration we do this 
986
    * only on startup and whenever we import a schema.
987
    */
988
 
989
   int ordinal = 0;
990
   TADOQuery * query = 0;
991
   try
992
   {
993
      query = new TADOQuery( this );
994
      query->Connection = Data_Module->IntegrationDBConnection;
995
 
996
      std::string structureHandle;
997
      std::string headerHandle;
998
      try
999
      {
1000
         if ( XMLSchema->Create(
1001
               schema.c_str(),
1002
               transactionStructureName.c_str(),
1003
               iteration,
1004
               structureHandle,
1005
 
1006
         {
1007
            if ( XMLSchema->Create(
1008
                  schema.c_str(),
1009
                  headerStructureName.c_str(),
1010
                  iteration,
1011
                  headerHandle,
1012
 
1013
            {
1014
               try
1015
               {
1016
                  // KI note. this txn had to be lost as there was an overlapping txn in progress
1017
                  // Data_Module->IntegrationDBConnection->BeginTrans();
1018
 
1019
                  TransactionSpecification & transaction = transactionCache.getTransactionSpecification( transactionSpecification );
1020
                  readTransactionSpecifications( transaction, transactionSpecification );
1021
 
1022
                  buildTransactionSpecificationValues(
1023
                     *query,
1024
                     transactionStructureName,
1025
                     testScenario,
1026
                     transactionSpecification,
1027
                     structureHandle,
1028
                     ordinal = 0,
1029
                     transaction );
1030
                  buildTransactionSpecificationValues(
1031
                     *query,
1032
                     headerStructureName,
1033
                     testScenario,
1034
                     transactionSpecification,
1035
                     headerHandle,
1036
                     ordinal = 0,
1037
                     transaction );
1038
 
1039
 
1040
                    // Data_Module->IntegrationDBConnection->CommitTrans(); 
1041
               }
1042
               catch ( const std::exception & exception )
1043
               {
1044
                  std::stringstream stream;
1045
                  stream
1046
                     << "Cannot build transaction specification values for \"" \
1047
                     << transactionStructureName \
1048
                     << "\".  " \
1049
                     << exception.what();
1050
                  MessageDlg(
1051
                     stream.str().c_str(),
1052
                     mtError, TMsgDlgButtons() << mbOK, 0 );
1053
 
1054
                  transactionCache.deleteTransactionSpecification( transactionSpecification );
1055
                  // Data_Module->IntegrationDBConnection->RollbackTrans();  // see comment above
1056
               }
1057
               catch ( ... )
1058
               {
1059
                  std::stringstream stream;
1060
                  stream
1061
                     << "Cannot build transaction specification values for \"" \
1062
                     << transactionStructureName \
1063
                     << "\".";
1064
                  MessageDlg(
1065
                     stream.str().c_str(),
1066
                     mtError, TMsgDlgButtons() << mbOK, 0 );
1067
 
1068
                  transactionCache.deleteTransactionSpecification( transactionSpecification );
1069
                  // Data_Module->IntegrationDBConnection->RollbackTrans(); // see comment above
1070
                  throw;
1071
               }
1072
            }
1073
            else
1074
            {
1075
               std::stringstream stream;
1076
               stream
1077
                  << "Cannot create structure \""
1078
                  << headerStructureName
1079
                  << "\" for iteration "
1080
                  << iteration << ".  Is \""
1081
                  << XMLSchema->Profile.c_str() << "\" configured correctly?";
1082
               MessageDlg(
1083
                  stream.str().c_str(),
1084
                  mtError, TMsgDlgButtons() << mbOK, 0 );
1085
            }
1086
         }
1087
         else
1088
         {
1089
            std::stringstream stream;
1090
            stream
1091
               << "Cannot create structure \""
1092
               << transactionStructureName
1093
               << "\" for iteration "
1094
               << iteration << ".  Is \""
1095
               << XMLSchema->Profile.c_str() << "\" configured correctly?";
1096
            MessageDlg(
1097
               stream.str().c_str(),
1098
               mtError, TMsgDlgButtons() << mbOK, 0 );
1099
         }
1100
      }
1101
      __finally
1102
      {
1103
         XMLSchema->Destroy( headerHandle );
1104
         XMLSchema->Destroy( structureHandle );
1105
      }
1106
   }
1107
   __finally
1108
   {
1109
      delete query;
1110
      query = 0;
1111
   }
1112
}
1113
//---------------------------------------------------------------------------
1114
 
1115
void __fastcall TMainForm::buildTransactionSpecificationFieldValue(
1116
               TADOQuery &             query,
1117
               const std::string &        rootStructure,
1118
               const std::string &        fieldHandle,
1119
               const int &             testScenario,
1120
               const int &             transactionSpecification,
1121
               int &                ordinal,
1122
               const &                 childCount,
1123
               TransactionSpecification & transactions,
1124
               const int &             subscript )
1125
{
1126
   std::string tagValue;
1127
 
1128
   // If we get a tag, then use it.  Otherwise, tough luck.
1129
   if ( !XMLSchema->GetAttributeProperty( fieldHandle, "tag", tagValue ) ||
1130
       tagValue.length() > 0 )
1131
   {
1132
      std::string fieldName;
1133
      std::string xPath;
1134
 
1135
      if ( XMLSchema->GetAttributeProperty( fieldHandle, "name", fieldName ) &&
1136
          XMLSchema->GetAttributeProperty( fieldHandle, "xpath", xPath ) )
1137
      {
1138
         /**
1139
          * Build the full xpath as the schema reports only the path
1140
          * relative to the root structure.
1141
          */
1142
         const std::string fullXPath = "/" + rootStructure + xPath;
1143
 
1144
         AnsiString displayName;
1145
         if ( !subscript )
1146
         {
1147
            displayName = fieldName.c_str();
1148
         }
1149
         else
1150
         {
1151
#if TDBADVGRID_FIXED
1152
            displayName.sprintf( "[%d]", subscript );
1153
#else
1154
            displayName.sprintf( "%s[%d]", fieldName.c_str(), subscript );
1155
#endif
1156
         }
1157
 
1158
         /**
1159
          * Work out whether we have to insert or update, and whether we
1160
          * have to migrate or not.
1161
          */
1162
         bool insert    = false;
1163
         bool migrate   = false;
1164
         if ( transactions.isContained( fullXPath ) )
1165
         {
1166
            insert = false;
1167
            migrate = false;
1168
         }
1169
         else
1170
         {
1171
            if ( transactions.isContained( xPath ) )
1172
            {
1173
               insert = false;
1174
               migrate = true;
1175
            }
1176
            else
1177
            {
1178
               insert = true;
1179
               migrate = false;
1180
            }
1181
         }
1182
 
1183
         /**
1184
          * We now assert this value into the database.
1185
          */
1186
         std::stringstream stream;
1187
         if ( !insert )
1188
         {
1189
            if ( !migrate )
1190
            {
1191
               stream << "UPDATE TXNSPEC_VALUES SET "
1192
                     << "CHILD_COUNT=" << childCount << ','
1193
                     << "DISPLAY_FIELDNAME=\'" << Utilities::EscapeString( displayName ).c_str() << "\',"
1194
                     << "FIELDNAME=\'" << Utilities::EscapeString( fieldName ) << "\',"
1195
                     << "FIELDTAG=" << atoi( tagValue.c_str() ) << ','
1196
                     << "ORDINAL=" << ++ordinal << ','
1197
                     << "SUBSCRIPT=" << subscript << ','
1198
                     << "TESTSCENARIO_NO=" << testScenario
1199
                  << " WHERE "
1200
                     << "TXNSPEC_NO=\'" << transactionSpecification << "\' AND "
1201
                     << "XPATH=\'" << fullXPath << '\'';
1202
               transactions.markValue( fullXPath );
1203
            }
1204
            else
1205
            {
1206
               stream << "UPDATE TXNSPEC_VALUES SET "
1207
                     << "CHILD_COUNT=" << childCount << ','
1208
                     << "DISPLAY_FIELDNAME=\'" << Utilities::EscapeString( displayName ).c_str() << "\',"
1209
                     << "FIELDNAME=\'" << Utilities::EscapeString( fieldName ) << "\',"
1210
                     << "FIELDTAG=" << atoi( tagValue.c_str() ) << ','
1211
                     << "ORDINAL=" << ++ordinal << ','
1212
                     << "SUBSCRIPT=" << subscript << ','
1213
                     << "TESTSCENARIO_NO=" << testScenario << ','
1214
                     << "XPATH=\'" << fullXPath << '\''
1215
                  << " WHERE "
1216
                     << "TXNSPEC_NO=\'" << transactionSpecification << "\' AND "
1217
                     << "XPATH=\'" << xPath << '\'';
1218
               transactions.markValue( xPath );
1219
            }
1220
         }
1221
         else
1222
         {
1223
            stream << "INSERT INTO TXNSPEC_VALUES ( "
1224
                  "TXNSPEC_NO,"
1225
                  "XPATH,"
1226
                  "CHILD_COUNT,"
1227
                  "DISPLAY_FIELDNAME,"
1228
                  "FIELDNAME,"
1229
                  "FIELDTAG,"
1230
                  "OBSOLETE,"
1231
                  "ORDINAL,"
1232
                  "SUBSCRIPT,"
1233
                  "TESTSCENARIO_NO,"
1234
                  "USER_SUPPLIED,"
1235
                  "DISPLAYABLE"
1236
               " ) VALUES ( "
1237
                  << transactionSpecification << ",\'"
1238
                  << fullXPath << "\',"
1239
                  << childCount << ",\'"
1240
                  << Utilities::EscapeString( displayName ).c_str() << "\',\'"
1241
                  << Utilities::EscapeString( fieldName ).c_str() << "\',"
1242
                  << atoi( tagValue.c_str() ) << ','
1243
                  << "\'N\'" << ','
1244
                  << ++ordinal << ','
1245
                  << subscript << ','
1246
                  << testScenario << ','
1247
                  << "\'N\'" << ','
1248
            << "\'N\'"
1249
               << " )";
1250
         }
1251
 
1252
         query.SQL->Text = stream.str().c_str();
1253
         if ( query.ExecSQL() != 1 )
1254
         {
1255
            MTHROW( std::runtime_error, \
1256
               "Cannot update field \"" \
1257
               << fullXPath \
1258
               << "\" of transaction specification " \
1259
               << transactionSpecification \
1260
               << '.' );
1261
         }
1262
      }
1263
      else
1264
      {
1265
         MTHROW( std::runtime_error, \
1266
            "Cannot get name and xpath for schema element \"" \
1267
            << fieldHandle \
1268
            << "\"." );
1269
      }
1270
   }
1271
   else
1272
   {
1273
      MTHROW( std::runtime_error, \
1274
         "Cannot get tag value for schema element \"" \
1275
         << fieldHandle \
1276
         << "\".  The tag is present but has a zero-length value." );
1277
   }
1278
}
1279
//---------------------------------------------------------------------------
1280
 
1281
void __fastcall TMainForm::buildTransactionSpecificationRepeatValue(
1282
               TADOQuery &             query,
1283
               const std::string &        rootStructure,
1284
               const std::string &        attribute,
1285
               const int &             testScenario,
1286
               const int &             transactionSpecification,
1287
               const std::string &        transactionStructureHandle,
1288
               int &                ordinal,
1289
               TransactionSpecification & transactions,
1290
               const int &             repeatLimit )
1291
{
1292
   std::string refcountField;
1293
   std::string repeatSize;
1294
 
1295
   /**
1296
    * Find the upper bound of the repeat by looking for the "max" property
1297
    * of the "refcountfield" (possibly an xPath), and then for our
1298
    * "maxOccurs" property.
1299
    */
1300
   XMLSchema->GetAttributeProperty( attribute, "refcountfield", refcountField );
1301
   if ( refcountField.length() )
1302
   {
1303
      XMLSchema->GetAttributeProperty(
1304
         transactionStructureHandle + "." + refcountField,
1305
         "max",
1306
         repeatSize );
1307
   }
1308
 
1309
   if ( !repeatSize.length() )
1310
   {
1311
      XMLSchema->GetAttributeProperty(
1312
         attribute,
1313
         "maxOccurs",
1314
         repeatSize );
1315
   }
1316
 
1317
   if ( repeatSize.length() )
1318
   {
1319
      /**
1320
       * Now instantiate the array so that we may traverse it, but limit it to
1321
       * repeatLimit elements.
1322
       */
1323
      const int   size = std::min< int >( atoi( repeatSize.c_str() ), repeatLimit );
1324
      std::string    repeatName;
1325
 
1326
      if ( ( refcountField.length() == 0 ) ||
1327
          XMLSchema->SetAttributeValue( transactionStructureHandle, refcountField, size ) )
1328
      {
1329
         if ( XMLSchema->GetAttributeProperty( attribute, "name", repeatName ) )
1330
         {
1331
            AnsiString  repeatElement;
1332
            std::string    datatype;
1333
            repeatElement.sprintf( "%s.1.%s",
1334
               attribute.c_str(),
1335
               repeatName.c_str() );
1336
            if ( XMLSchema->GetAttributeProperty(
1337
                  repeatElement.c_str(),
1338
                  "datatype",
1339
                  datatype ) )
1340
            {
1341
               const bool isStruct = ( datatype == "Struct" );
1342
               buildTransactionSpecificationFieldValue(
1343
                  query,
1344
                  rootStructure,
1345
                  attribute,
1346
                  testScenario,
1347
                  transactionSpecification,
1348
                  ordinal,
1349
                  countChildren( attribute, isStruct ),
1350
                  transactions );
1351
               if ( size >= 1 )
1352
               {
1353
                  std::string repeatHandle;
1354
                  for ( int where = 1; where <= size; ++where )
1355
                  {
1356
                     repeatElement.sprintf( "%s.%d.%s",
1357
                        attribute.c_str(),
1358
                        where,
1359
                        repeatName.c_str() );
1360
                     repeatHandle = repeatElement.c_str();
1361
                     if ( isStruct )
1362
                     {
1363
                        buildTransactionSpecificationFieldValue(
1364
                           query,
1365
                           rootStructure,
1366
                           repeatHandle,
1367
                           testScenario,
1368
                           transactionSpecification,
1369
                           ordinal,
1370
                           countChildren( repeatHandle, isStruct ),
1371
                           transactions,
1372
                           where );
1373
                        buildTransactionSpecificationValues(
1374
                           query,
1375
                           rootStructure,
1376
                           testScenario,
1377
                           transactionSpecification,
1378
                           repeatHandle,
1379
                           ordinal,
1380
                           transactions );
1381
                     }
1382
                     else
1383
                     {
1384
                        buildTransactionSpecificationFieldValue(
1385
                           query,
1386
                           rootStructure,
1387
                           repeatHandle,
1388
                           testScenario,
1389
                           transactionSpecification,
1390
                           ordinal,
1391
                           0,
1392
                           transactions,
1393
                           where );
1394
                     }
1395
                  }
1396
               }
1397
            }
1398
            else
1399
            {
1400
               MTHROW( std::runtime_error, \
1401
                  "Cannot get datatype for schema element \"" \
1402
                  << repeatElement.c_str() \
1403
                  << "\"." );
1404
            }
1405
         }
1406
         else
1407
         {
1408
            MTHROW( std::runtime_error, \
1409
               "Cannot get name for schema element \"" \
1410
               << attribute \
1411
               << "\"." );
1412
         }
1413
      }
1414
      else
1415
      {
1416
         MTHROW( std::runtime_error, \
1417
            "Cannot set size for schema element \"" \
1418
            << transactionStructureHandle + "." + refcountField \
1419
            << "\"." );
1420
      }
1421
   }
1422
   else
1423
   {
1424
      MTHROW( std::runtime_error, \
1425
         "Cannot get repeat size for schema element \"" \
1426
         << attribute \
1427
         << "\"." );
1428
   }
1429
}
1430
//---------------------------------------------------------------------------
1431
 
1432
void __fastcall TMainForm::buildTransactionSpecificationValues(
1433
               TADOQuery &             query,
1434
               const std::string &        rootStructure,
1435
               const int &             testScenario,
1436
               const int &             transactionSpecification,
1437
               const std::string &        transactionStructureHandle,
1438
               int &                ordinal,
1439
               TransactionSpecification & transactions )
1440
{
1441
   std::vector< std::string > attributes;
1442
 
1443
   if ( XMLSchema->GetAttributes( transactionStructureHandle, attributes ) )
1444
   {
1445
      std::string elementType;
1446
 
1447
      for ( std::vector< std::string >::iterator
1448
            where = attributes.begin();
1449
           where != attributes.end();
1450
           ++where )
1451
      {
1452
         if ( XMLSchema->GetAttributeProperty( *where, "type", elementType ) )
1453
         {
1454
            std::string elementDatatype;
1455
 
1456
            if ( elementType == "field" )
1457
            {
1458
               if ( XMLSchema->GetAttributeProperty( *where, "datatype", elementDatatype ) )
1459
               {
1460
                  const isStruct = ( elementDatatype == "Struct" );
1461
 
1462
                  buildTransactionSpecificationFieldValue(
1463
                     query,
1464
                     rootStructure,
1465
                     *where,
1466
                     testScenario,
1467
                     transactionSpecification,
1468
                     ordinal,
1469
                     ( isStruct ? countChildren( *where, false ) : 0 ),
1470
                     transactions );
1471
                  if ( isStruct )
1472
                  {
1473
                     buildTransactionSpecificationValues(
1474
                        query,
1475
                        rootStructure,
1476
                        testScenario,
1477
                        transactionSpecification,
1478
                        *where,
1479
                        ordinal,
1480
                        transactions );
1481
                  }
1482
               }
1483
               else
1484
               {
1485
                  MTHROW( std::runtime_error, \
1486
                     "Cannot get datatype for schema element \"" \
1487
                     << *where \
1488
                     << "\"." );
1489
               }
1490
            }
1491
            else if ( elementType == "repeat" )
1492
            {
1493
               buildTransactionSpecificationRepeatValue(
1494
                  query,
1495
                  rootStructure,
1496
                  *where,
1497
                  testScenario,
1498
                  transactionSpecification,
1499
                  transactionStructureHandle,
1500
                  ordinal,
1501
                  transactions );
1502
            }
1503
         }
1504
         else
1505
         {
1506
            MTHROW( std::runtime_error, \
1507
               "Cannot get type for schema element \"" \
1508
               << *where \
1509
               << "\"." );
1510
         }
1511
      }
1512
   }
1513
   else
1514
   {
1515
      MTHROW( std::runtime_error, \
1516
         "Cannot get attributes for schema element \"" \
1517
         << transactionStructureHandle \
1518
         << "\"." );
1519
   }
1520
}
1521
//---------------------------------------------------------------------------
1522
 
1523
const unsigned __fastcall TMainForm::countChildren( const std::string & transactionStructureHandle, const bool & isStructureRepeat )
1524
{
1525
   unsigned             childCount = 0;
1526
   std::vector< std::string > attributes;
1527
 
1528
   if ( XMLSchema->GetAttributes( transactionStructureHandle, attributes ) )
1529
   {
1530
      std::string elementType;
1531
      std::string elementDatatype;
1532
 
1533
      for ( std::vector< std::string >::iterator
1534
            where = attributes.begin();
1535
           where != attributes.end();
1536
           ++where )
1537
      {
1538
         if ( XMLSchema->GetAttributeProperty( *where, "type", elementType ) )
1539
         {
1540
//          if ( !isStructureRepeat )
1541
//          {
1542
               ++childCount;
1543
//          }
1544
            if ( elementType == "field" )
1545
            {
1546
               if ( XMLSchema->GetAttributeProperty( *where, "datatype", elementDatatype ) )
1547
               {
1548
                  if ( elementDatatype == "Struct" )
1549
                  {
1550
                     childCount += countChildren( *where, false );
1551
                  }
1552
               }
1553
               else
1554
               {
1555
                  MTHROW( std::runtime_error, \
1556
                     "Cannot get datatype for schema element \"" \
1557
                     << *where \
1558
                     << "\"." );
1559
               }
1560
            }
1561
            else if ( elementType == "repeat" )
1562
            {
1563
               childCount += countChildren( *where, transactionStructureHandle );
1564
            }
1565
         }
1566
         else
1567
         {
1568
            MTHROW( std::runtime_error, \
1569
               "Cannot get type for schema element \"" \
1570
               << *where \
1571
               << "\"." );
1572
         }
1573
      }
1574
   }
1575
   else
1576
   {
1577
      MTHROW( std::runtime_error, \
1578
         "Cannot get attributes for schema element \"" \
1579
         << transactionStructureHandle \
1580
         << "\"." );
1581
   }
1582
 
1583
   return ( childCount );
1584
}
1585
//---------------------------------------------------------------------------
1586
 
1587
const unsigned __fastcall TMainForm::countChildren(
1588
               const std::string &  attribute,
1589
               const std::string &     transactionStructureHandle,
1590
               const int &       repeatLimit )
1591
{
1592
   unsigned childCount = 0;
1593
   std::string refcountField;
1594
   std::string repeatSize;
1595
 
1596
   /**
1597
    * Find the upper bound of the repeat by looking for the "max" property
1598
    * of the "refcountfield" (possibly an xPath), and then for our
1599
    * "maxOccurs" property.
1600
    */
1601
   XMLSchema->GetAttributeProperty( attribute, "refcountfield", refcountField );
1602
   if ( refcountField.length() )
1603
   {
1604
      XMLSchema->GetAttributeProperty(
1605
         transactionStructureHandle + "." + refcountField,
1606
         "max",
1607
         repeatSize );
1608
   }
1609
 
1610
   if ( !repeatSize.length() )
1611
   {
1612
      XMLSchema->GetAttributeProperty(
1613
         attribute,
1614
         "maxOccurs",
1615
         repeatSize );
1616
   }
1617
 
1618
   if ( repeatSize.length() )
1619
   {
1620
      /**
1621
       * Now instantiate the array so that we may traverse it, but limit it to
1622
       * repeatLimit elements.
1623
       */
1624
      const int   size = std::min< int >( atoi( repeatSize.c_str() ), repeatLimit );
1625
      std::string    repeatName;
1626
 
1627
      if ( ( refcountField.length() == 0 ) ||
1628
          XMLSchema->SetAttributeValue( transactionStructureHandle, refcountField, size ) )
1629
      {
1630
         if ( XMLSchema->GetAttributeProperty( attribute, "name", repeatName ) )
1631
         {
1632
            if ( size >= 1 )
1633
            {
1634
               AnsiString  repeatElement;
1635
               std::string    datatype;
1636
               repeatElement.sprintf( "%s.1.%s",
1637
                  attribute.c_str(),
1638
                  repeatName.c_str() );
1639
               if ( XMLSchema->GetAttributeProperty(
1640
                     repeatElement.c_str(),
1641
                     "datatype",
1642
                     datatype ) )
1643
               {
1644
                  const isStruct = ( datatype == "Struct" );
1645
                  for ( int where = 1; where <= size; ++where )
1646
                  {
1647
                     repeatElement.sprintf( "%s.%d.%s",
1648
                        attribute.c_str(),
1649
                        where,
1650
                        repeatName.c_str() );
1651
                     if ( !isStruct )
1652
                     {
1653
                        ++childCount;
1654
                     }
1655
                     else
1656
                     {
1657
                        childCount += countChildren( repeatElement.c_str(), false ) + 1;
1658
                     }
1659
                  }
1660
               }
1661
               else
1662
               {
1663
                  MTHROW( std::runtime_error, \
1664
                     "Cannot get datatype for schema element \"" \
1665
                     << repeatElement.c_str() \
1666
                     << "\"." );
1667
               }
1668
            }
1669
         }
1670
         else
1671
         {
1672
            MTHROW( std::runtime_error, \
1673
               "Cannot get name for schema element \"" \
1674
               << attribute \
1675
               << "\"." );
1676
         }
1677
      }
1678
      else
1679
      {
1680
         MTHROW( std::runtime_error, \
1681
            "Cannot set size for schema element \"" \
1682
            << transactionStructureHandle + "." + refcountField \
1683
            << "\"." );
1684
      }
1685
   }
1686
   else
1687
   {
1688
      MTHROW( std::runtime_error, \
1689
         "Cannot get repeat size for schema element \"" \
1690
         << attribute \
1691
         << "\"." );
1692
   }
1693
   return ( childCount );
1694
}
1695
//---------------------------------------------------------------------------
1696
 
1697
void __fastcall TMainForm::clearTransactionSpecificationValueTree( TDBAdvGrid & grid )
1698
{
1699
#if TDBADVGRID_FIXED
1700
   grid.RemoveAllNodes();
1701
#endif
1702
}
1703
//---------------------------------------------------------------------------
1704
 
1705
const int TMainForm::countChildNodes( TDBAdvGrid & grid, TADOQuery & query, const int & row, const int & rows )
1706
{
1707
   query.RecNo = row;   // Move the cursor to the row we're looking at.
1708
 
1709
   int               count    = 0;
1710
   const AnsiString  parentPath  = query.FieldByName( "XPATH" )->AsString;
1711
 
1712
   for ( int where = row + 1; where <= rows; ++where )
1713
   {
1714
      query.RecNo = where;
1715
 
1716
      if ( parentPath == query.FieldByName( "XPATH" )
1717
                        ->AsString.SubString( 1, parentPath.Length() ) )
1718
      {
1719
         ++count;
1720
      }
1721
      else
1722
      {
1723
         break;
1724
      }
1725
 
1726
   }
1727
 
1728
   return ( count );
1729
}
1730
//---------------------------------------------------------------------------
1731
 
1732
void __fastcall TMainForm::buildTransactionSpecificationValueTree( TDBAdvGrid & grid, TADOQuery & query )
1733
{
1734
#if TDBADVGRID_FIXED
1735
   grid.BeginUpdate();
1736
   const int currentRow = query.RecNo;
1737
   try
1738
   {
1739
      int children   = 0;
1740
      const int rows = query.RecordCount;
1741
      for ( int where = 1; where <= rows; ++where )
1742
      {
1743
         if ( ( children = countChildNodes( grid, query, where, rows ) ) > 0 )
1744
         {
1745
            grid.AddNode( where, 1 + children );
1746
         }
1747
      }
1748
   }
1749
   __finally
1750
   {
1751
      grid.ContractAll();
1752
      query.RecNo = currentRow;
1753
      grid.EndUpdate();
1754
   }
1755
#endif
1756
}
1757
//---------------------------------------------------------------------------
1758
 
1759
void __fastcall TMainForm::getParentOrdinals( std::vector< int > & parents )
1760
{
1761
   TADOQuery * query = 0;
1762
   try
1763
   {
1764
      parents.clear();
1765
 
1766
      query = new TADOQuery( this );
1767
      query->Connection = Data_Module->IntegrationDBConnection;
1768
 
1769
      AnsiString  sqlStatement;
1770
      sqlStatement.sprintf(
1771
         "SELECT "
1772
            "ORDINAL "
1773
         "FROM "
1774
            "TXNSPEC_VALUES "
1775
         "WHERE "
1776
            "TESTSCENARIO_NO=%d AND "
1777
            "TXNSPEC_NO=%d AND "
1778
            "CHILD_COUNT > 0",
1779
         m_testscenario_no,
1780
         m_txnspec_no );
1781
      query->SQL->Text = sqlStatement;
1782
      query->Open();
1783
      while ( !query->Eof )
1784
      {
1785
         parents.push_back( query->FieldByName( "ORDINAL" )->AsInteger );
1786
         query->Next();
1787
      }
1788
   }
1789
   __finally
1790
   {
1791
      delete query;
1792
      query = 0;
1793
   }
1794
}
1795
//---------------------------------------------------------------------------
1796
 
1797
void __fastcall TMainForm::populatePayloadStructureTab( const AnsiString & structure )
1798
{
1799
   AnsiString  sqlStatement;
1800
 
1801
   PayloadStructureTabSheet->TabVisible = true;
1802
   PayloadStructureTabSheet->Caption = structure;
1803
 
1804
   TxnValuesQuery->Close();
1805
#if TDBADVGRID_FIXED
1806
   clearTransactionSpecificationValueTree( *NewPayloadStructureGrid );
1807
#endif
1808
   sqlStatement.sprintf(
1809
      "SELECT "
1810
         "* "
1811
      "FROM "
1812
         "TXNSPEC_VALUES "
1813
      "WHERE "
1814
         "TESTSCENARIO_NO=%d AND "
1815
         "TXNSPEC_NO=%d AND "
1816
         "XPATH LIKE \'/%s/%%\' AND "
1817
         "DISPLAYABLE = \'Y\' AND "       
1818
         "OBSOLETE=\'N\' "
1819
#if !INCLUDE_PARENTS
1820
         "AND CHILD_COUNT=0 "
1821
#endif
1822
      "ORDER BY "
1823
         "ORDINAL,"
1824
         "FIELDNAME,"
1825
         "SUBSCRIPT",
1826
      m_testscenario_no,
1827
      m_txnspec_no,
1828
      structure.c_str() );
1829
 
1830
   TxnValuesQuery->SQL->Text = sqlStatement;
1831
   TxnValuesQuery->Open();
1832
 
1833
#if TDBADVGRID_FIXED
1834
   buildTransactionSpecificationValueTree( *NewPayloadStructureGrid, *TxnValuesQuery );
1835
#endif
1836
#if INCLUDE_PARENTS
1837
   getParentOrdinals( m_parents );
1838
#endif
1839
}
1840
//---------------------------------------------------------------------------
1841
 
1842
void __fastcall TMainForm::populateHeaderStructureTab( const AnsiString & structure )
1843
{
1844
   AnsiString sqlStatement;
1845
 
1846
   HeaderStructureTabSheet->TabVisible = false;
1847
   HeaderStructureTabSheet->Caption = structure;
1848
 
1849
   TxnHeaderValuesQuery->Close();
1850
 
1851
   sqlStatement.sprintf(
1852
      "SELECT "
1853
         "* "
1854
      "FROM "
1855
         "TXNSPEC_VALUES "
1856
      "WHERE "
1857
         "TESTSCENARIO_NO=%d AND "
1858
         "TXNSPEC_NO=%d AND "
1859
         "XPATH LIKE \'/%s/%%\' AND "
1860
         "OBSOLETE=\'N\' "
1861
      "ORDER BY "
1862
         "ORDINAL,"
1863
         "FIELDNAME,"
1864
         "SUBSCRIPT",
1865
      m_testscenario_no,
1866
      m_txnspec_no,
1867
      structure.c_str() );
1868
 
1869
   TxnHeaderValuesQuery->SQL->Text = sqlStatement;
1870
   TxnHeaderValuesQuery->Open();
1871
}
1872
 
1873
//---------------------------------------------------------------------------
1874
 
1875
void __fastcall TMainForm::TestCaseTreeViewChange(TObject *Sender,
1876
     TTreeNode *Node)
1877
{
1878
   TestCaseTreeViewEnter(Sender);
1879
 
1880
   AnsiString  sql_statement;
1881
 
1882
    // Only update when TestCase nodes
1883
    if (Node->Level == 0)
1884
    {
1885
      // ----------------- TEST CASE -----------------
1886
      TestCasePanel->Caption = Node->Text;
1887
      MainPageControl->ActivePage = ScenarioStepsTabSheet;
1888
 
1889
      m_testscenario_no = (int)(Node->Data);
1890
      m_txnspec_no = 0;
1891
      m_structure_name="";
1892
 
1893
      TxnValuesQuery->Close();
1894
      TxnHeaderValuesQuery->Close();
1895
 
1896
 
1897
      //TransactionStructurePageControl->ActivePage = PayloadStructureTabSheet;
1898
      //PayloadStructureTabSheet->Caption = "Payload Structure";
1899
      //HeaderStructureTabSheet->Caption = "Header Structure";
1900
      //HeaderStructureTabSheet->TabVisible = false;
1901
 
1902
 
1903
      m_parents.clear();
1904
 
1905
/*    
1906
      TxnStepsQuery->Close();
1907
      sql_statement="";
1908
      sql_statement.sprintf("SELECT TESTCASE_SEQNO, NAME, REPEAT_COUNT, DESCRIPTION "
1909
                            "FROM TEST_SCENARIOS "
1910
                       "WHERE TESTCASE_ID = \'%s\' "
1911
                       "ORDER BY TESTCASE_SEQNO",
1912
                       m_currenttestcaseid);
1913
 
1914
      TxnStepsQuery->SQL->Text = sql_statement;
1915
      TxnStepsQuery->Open();
1916
      TxnStepsQuery->Edit();
1917
*/ 
1918
      // ---------------------------------------------
1919
   }
1920
   else
1921
   if (Node->Level == 1)
1922
   {
1923
      // ---------------- TRANSACTION ----------------
1924
 
1925
      TestCasePanel->Caption = Node->Parent->Text;
1926
      MainPageControl->ActivePage = TestScenariosTabSheet;
1927
 
1928
      m_testscenario_no    = (int)(Node->Parent->Data);
1929
      m_txnspec_no      = (int)(Node->Data);
1930
      m_structure_name  = Node->Text.c_str();
1931
 
1932
      TransactionStructurePageControl->ActivePage = PayloadStructureTabSheet;
1933
      if ( !m_transactionCache.isContained( m_txnspec_no ) )
1934
      {
1935
         const TCursor Save_Cursor = Screen->Cursor;
1936
         try
1937
         {
1938
            Screen->Cursor = crHourGlass;
1939
 
1940
            AnsiString message;
1941
            message.sprintf(
1942
               " Building %s ...",
1943
               Node->Text.c_str() );
1944
            MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
1945
            Application->ProcessMessages();
1946
 
1947
 
1948
            buildTransactionSpecificationValues(
1949
               m_transactionCache,
1950
               m_testscenario_no,
1951
               m_txnspec_no,
1952
               Node->Text.c_str(),
1953
               g_headerStructure,
1954
               m_schema_handle,
1955
               m_currentiteration );
1956
         }
1957
         __finally
1958
         {
1959
            Screen->Cursor = Save_Cursor;
1960
         }
1961
      }
1962
      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "";
1963
 
1964
      populateHeaderStructureTab( g_headerStructure );
1965
      populatePayloadStructureTab( Node->Text );
1966
 
1967
 
1968
//    if (TxnStepsQuery->State == dsEdit) TxnStepsQuery->Post();
1969
//    TxnStepsQuery->Close();
1970
/*    sql_statement="";
1971
      sql_statement.sprintf("SELECT TESTCASE_SEQNO, NAME, REPEAT_COUNT, DESCRIPTION FROM TEST_SCENARIOS "
1972
                       "WHERE TESTCASE_ID = \'%s\' "
1973
                       "ORDER BY TESTCASE_SEQNO",
1974
                       m_currenttestcaseid);
1975
      TxnStepsQuery->SQL->Text = sql_statement;
1976
*/    
1977
//    if(!TxnStepsQuery->Active)
1978
//    {
1979
//       TxnStepsQuery->Open();
1980
//       TxnStepsQuery->Edit();
1981
//    }
1982
      // ---------------------------------------------
1983
   }
1984
}
1985
//---------------------------------------------------------------------------
1986
 
1987
void __fastcall TMainForm::NewTransactionActionExecute(TObject *Sender)
1988
{
1989
   TTreeNode   *current_node = TestCaseTreeView->Selected;
1990
 
1991
    if (current_node != NULL)
1992
    {
1993
      if (current_node->Level == 0) // Add Txn
1994
      {
1995
         AnsiString  testcase_text = current_node->Text;
1996
 
1997
         int   testscenario_no = (int)(current_node->Data);
1998
 
1999
         if ( TxnConfig->ShowForm(m_currentproject, m_currentiteration, testcase_text) == true)
2000
            {
2001
                TxnSpecQuery->Close();
2002
 
2003
                const TCursor Save_Cursor = Screen->Cursor;
2004
 
2005
                TADOQuery *   query = new TADOQuery(this);
2006
                AnsiString sql_statement;
2007
                query->Connection = Data_Module->IntegrationDBConnection;
2008
 
2009
                /* prepare to apply templates to new transaction(s) */
2010
                TestScenarioTemplate * all   = m_transactionTemplates.findTestScenarioTemplate( 0 );
2011
                TADOQuery *   txn_query = new TADOQuery(this);
2012
                txn_query->Connection = Data_Module->IntegrationDBConnection;
2013
 
2014
                try
2015
                {
2016
                   /* could not make atomic as buildtxnspecvalues has a transaction */
2017
                   //Data_Module->IntegrationDBConnection->BeginTrans(); 
2018
 
2019
                    sql_statement="";
2020
                    sql_statement.sprintf("SELECT MAX(SEQ_NO) AS MAXSEQ_NO "
2021
                                   "FROM TRANSACTION_SPECIFICATION "
2022
                                          "WHERE PROJECT_CODE='%s' AND ITERATION=%d AND TESTSCENARIO_NO=%d",
2023
                                          m_currentproject.c_str(),
2024
                                m_currentiteration,
2025
                                          testscenario_no);
2026
 
2027
                    query->SQL->Text = sql_statement;
2028
                    query->Open();
2029
 
2030
                    int seq_no = query->FieldByName("MAXSEQ_NO")->AsInteger;
2031
                    seq_no++;
2032
 
2033
                    vector<unsigned int>       selected_txns = TxnConfig->getSelectedTxns();
2034
                    vector<unsigned int>::iterator selected_txn_itr = selected_txns.begin();
2035
                    const unsigned count = selected_txns.end() - selected_txns.begin() + 1;
2036
                    m_progressBar->open( count * 2 ); 
2037
 
2038
                    Screen->Cursor = crHourGlass;
2039
                    AnsiString message;
2040
                    message.sprintf(" Building %d new transactions ...", count );
2041
                    MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
2042
                    Application->ProcessMessages();
2043
 
2044
                    while (selected_txn_itr != selected_txns.end())
2045
                    {
2046
                        unsigned int   txnindex = (*selected_txn_itr);
2047
                        unsigned short udtype    = txnindex >> 16;
2048
                        unsigned short udsubtype = txnindex & 0xffff;
2049
                        AnsiString txnname = "";
2050
 
2051
                        sql_statement="";
2052
                        sql_statement.sprintf("INSERT INTO TRANSACTION_SPECIFICATION "
2053
                                      "(PROJECT_CODE,ITERATION,TESTSCENARIO_NO,UDTYPE,UDSUBTYPE,SEQ_NO) "
2054
                                      "VALUES ('%s',%d,%d,%d,%d,%d) ",
2055
                                      m_currentproject.c_str(),
2056
                                      m_currentiteration,
2057
                                      testscenario_no,
2058
                                      udtype,
2059
                                      udsubtype,
2060
                                      seq_no);
2061
 
2062
                        query->SQL->Text = sql_statement;
2063
                        query->ExecSQL();
2064
 
2065
                        // now we have created the new transaction we can get its primary key ansd apply the template
2066
                        sql_statement="";                    
2067
 
2068
                        sql_statement.sprintf("SELECT MASS_TXNS.NAME,TRANSACTION_SPECIFICATION.TXNSPEC_NO "
2069
                          "FROM MASS_TXNS,TRANSACTION_SPECIFICATION "
2070
                          "WHERE TRANSACTION_SPECIFICATION.TESTSCENARIO_NO = %d "
2071
                          "AND   TRANSACTION_SPECIFICATION.ITERATION = %d"
2072
                          "AND   MASS_TXNS.PROJECTCODE=TRANSACTION_SPECIFICATION.PROJECT_CODE "
2073
                          "AND   MASS_TXNS.ITERATION=TRANSACTION_SPECIFICATION.ITERATION "
2074
                          "AND   MASS_TXNS.UDTYPE=TRANSACTION_SPECIFICATION.UDTYPE "
2075
                          "AND   MASS_TXNS.UDSUBTYPE=TRANSACTION_SPECIFICATION.UDSUBTYPE "
2076
                          "AND   TRANSACTION_SPECIFICATION.UDTYPE = %d "
2077
                          "AND   TRANSACTION_SPECIFICATION.UDSUBTYPE = %d "
2078
                          "AND   TRANSACTION_SPECIFICATION.SEQ_NO = %d ",
2079
                            testscenario_no,
2080
                            m_currentiteration,
2081
                            udtype,
2082
                            udsubtype,
2083
                            seq_no);
2084
 
2085
                        txn_query->SQL->Text = sql_statement;
2086
                        txn_query->Open();                                               
2087
 
2088
                        txnname = txn_query->FieldByName( "NAME" )->AsString;
2089
                        m_txnspec_no = txn_query->FieldByName( "TXNSPEC_NO" )->AsInteger;
2090
 
2091
                        // create txn spec values
2092
 
2093
                        buildTransactionSpecificationValues(
2094
                            m_transactionCache,
2095
                            m_testscenario_no,
2096
                            m_txnspec_no,
2097
                            txnname.c_str(),
2098
                            g_headerStructure,
2099
                            m_schema_handle,
2100
                            m_currentiteration );
2101
 
2102
 
2103
                         // now apply template
2104
 
2105
                        applyTemplatesToNewTransaction( m_txnspec_no, all);
2106
                        txn_query->Close();
2107
 
2108
                        m_progressBar->increment();
2109
 
2110
                        seq_no++;
2111
 
2112
                        selected_txn_itr++;
2113
                    }
2114
 
2115
                    //Data_Module->IntegrationDBConnection->CommitTrans(); //see comment above
2116
                }
2117
                catch(...)
2118
                {
2119
                    //Data_Module->IntegrationDBConnection->RollbackTrans(); //see comment above
2120
                }
2121
 
2122
                MainStatusBar->Panels->Items[ g_messagePanel ]->Text = ""; 
2123
                Screen->Cursor = Save_Cursor;
2124
                delete query;
2125
 
2126
                TxnSpecQuery->Open();
2127
 
2128
                LoadTestCaseNodes(current_node);
2129
                current_node->Expand(true);
2130
            }
2131
        }
2132
    }
2133
}
2134
//---------------------------------------------------------------------------
2135
 
2136
void __fastcall TMainForm::DeleteTransactionActionExecute(TObject *Sender)
2137
{
2138
   bool     refresh_testcases = false;
2139
 
2140
   for (unsigned selected_item=0; selected_item<TestCaseTreeView->SelectionCount; selected_item++)
2141
   {
2142
      TTreeNode   *current_node = TestCaseTreeView->Selections[selected_item];
2143
 
2144
      if (current_node!= NULL)
2145
      {
2146
         if (current_node->Level == 1) // Remove Test Case Transaction
2147
         {
2148
            // Confirm deletion
2149
            AnsiString  message;
2150
            message.sprintf( "Are you sure you want to delete transaction '%s'?", current_node->Text );
2151
 
2152
            if ( MessageDlg( message, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes )
2153
            {
2154
               int   testscenario_no = (int)(current_node->Parent->Data);
2155
               int   txnspec_no = (int)(current_node->Data);
2156
 
2157
               TADOQuery   *query = new TADOQuery(this);
2158
               AnsiString  sql_statement;
2159
               query->Connection = Data_Module->IntegrationDBConnection;
2160
 
2161
               try
2162
               {
2163
                  Data_Module->IntegrationDBConnection->BeginTrans();
2164
 
2165
                  sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES "
2166
                                   "WHERE TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d",
2167
                                   testscenario_no,
2168
                                   txnspec_no);
2169
 
2170
                  query->SQL->Text = sql_statement;
2171
                  query->ExecSQL();
2172
 
2173
                  sql_statement="";
2174
                  sql_statement.sprintf("DELETE FROM TRANSACTION_SPECIFICATION "
2175
                                   "WHERE PROJECT_CODE='%s' AND ITERATION=%d "
2176
                                   "AND   TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d ",
2177
                                   m_currentproject.c_str(),
2178
                                   m_currentiteration,
2179
                                   testscenario_no,
2180
                                   txnspec_no);
2181
 
2182
                  query->SQL->Text = sql_statement;
2183
                  query->ExecSQL();
2184
 
2185
                  Data_Module->IntegrationDBConnection->CommitTrans();
2186
 
2187
                  refresh_testcases = true;
2188
 
2189
                  ResequenceTransactions(current_node->Parent);
2190
               }
2191
               catch(...)
2192
               {
2193
                  Data_Module->IntegrationDBConnection->RollbackTrans();
2194
               }
2195
 
2196
               delete query;
2197
            }
2198
         }
2199
      }
2200
   }
2201
 
2202
   if (refresh_testcases)
2203
   {
2204
      bool allow;
2205
      TestCaseGridRowChanging(Sender, 0, 1, allow = true);
2206
   }
2207
}
2208
//---------------------------------------------------------------------------
2209
 
2210
 
2211
void __fastcall TMainForm::TestCaseZoomInClick(TObject *Sender)
2212
{
2213
   TestCaseTreeView->FullExpand();
2214
}
2215
//---------------------------------------------------------------------------
2216
 
2217
void __fastcall TMainForm::TestCaseZoomOutClick(TObject *Sender)
2218
{
2219
   TestCaseTreeView->FullCollapse();   
2220
}
2221
//---------------------------------------------------------------------------
2222
 
2223
AnsiString & TMainForm::getNameFromNode( AnsiString & name, const AnsiString & string )
2224
{
2225
    char const *p = string.c_str();
2226
 
2227
    name = string;
2228
    if ( *p && *p == '(' )
2229
    {
2230
        ++p;
2231
        while ( *p && isdigit( *p ) )
2232
        {
2233
            ++p;
2234
        }
2235
        if ( *p && *p == ')' )
2236
        {
2237
            ++p;
2238
            while ( *p && isspace( *p ) )
2239
            {
2240
                ++p;
2241
            }
2242
            if ( *p )
2243
            {
2244
                name = p;
2245
            }
2246
        }
2247
    }
2248
 
2249
   return ( name );
2250
}
2251
 
2252
 
2253
// delete a step via navigator button
2254
void __fastcall TMainForm::ScenarioStepsNavigatorBefore(TObject *Sender, TAdvNavigateBtn Button)
2255
{ 
2256
    AnsiString BtnName;
2257
    switch (Button)
2258
    {
2259
        case Dbctrls::nbFirst:  BtnName = "First Record"; break;
2260
        case Dbctrls::nbPrior:  BtnName = "Prior Record"; break;
2261
        case Dbctrls::nbNext:   BtnName = "Next Record"; break;
2262
        case Dbctrls::nbLast:   BtnName = "Last Record"; break;
2263
        case Dbctrls::nbInsert: 
2264
        {  
2265
             BtnName = "Insert Record";
2266
             break;
2267
        }
2268
        case Dbctrls::nbDelete: BtnName = "Delete Record"; 
2269
        {  
2270
            BtnName = "Delete Record";
2271
            AnsiString  message;
2272
            int myRow = StepsGrid->GetRealRow();
2273
         message.sprintf( 
2274
                            "Are you sure you want to delete all transactions from test step ('%s') %s? ",
2275
                             StepsGrid->Cells[1][myRow],
2276
                             StepsGrid->Cells[2][myRow] );
2277
 
2278
         if ( MessageDlg( message, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes )
2279
         {
2280
                int scenario = TxnStepsQuery->FieldByName( "TESTSCENARIO_NO" )->AsInteger;
2281
                DeleteScenarioChildren(scenario); 
2282
            }     
2283
            break;
2284
        }        
2285
        case Dbctrls::nbEdit:   BtnName = "Edit"; break;
2286
 
2287
        case Dbctrls::nbCancel: BtnName = "Cancel Edits"; break;
2288
        case Dbctrls::nbRefresh: BtnName = "Refresh Data"; break;
2289
        default: BtnName = "Other"; break;
2290
    }
2291
 
2292
}
2293
 
2294
// add a new step via navigator button
2295
void __fastcall TMainForm::ScenarioStepsNavigatorClick(TObject *Sender, TAdvNavigateBtn Button)
2296
{ 
2297
    AnsiString BtnName;
2298
   bool     refresh_testcases = false;
2299
    switch (Button)
2300
    {
2301
        case Dbctrls::nbFirst:  BtnName = "First Record"; break;
2302
        case Dbctrls::nbPrior:  BtnName = "Prior Record"; break;
2303
        case Dbctrls::nbNext:   BtnName = "Next Record"; break;
2304
        case Dbctrls::nbLast:   BtnName = "Last Record"; break;
2305
        case Dbctrls::nbInsert: 
2306
        {  
2307
             BtnName = "Insert Record";
2308
             refresh_testcases = false;
2309
             AddTestCaseNodeClick(Sender);            
2310
             TTreeNode*    dummyNode;
2311
             ResequenceTestCases(dummyNode);
2312
             TxnStepsQuery->Edit();
2313
             break;
2314
        }
2315
        case Dbctrls::nbDelete: BtnName = "Delete Record"; 
2316
        {  
2317
             BtnName = "Delete Record";
2318
             refresh_testcases = true; 
2319
             break;
2320
        }        
2321
        case Dbctrls::nbEdit:   BtnName = "Edit"; break;
2322
 
2323
        case Dbctrls::nbCancel: BtnName = "Cancel Edits"; break;
2324
        case Dbctrls::nbRefresh: BtnName = "Refresh Data"; break;
2325
        default: BtnName = "Other"; break;
2326
    }
2327
 
2328
 
2329
    //for (int J = 0; J < StepsGrid->RowCount; J++)
2330
    //    StepsGrid->Cells[0][J] = IntToStr(J+1);
2331
 
2332
 
2333
 
2334
    //BtnName = BtnName + " button clicked.";
2335
    //Application->MessageBox(BtnName.c_str() , "Navigator", MB_OK);
2336
 
2337
   if (refresh_testcases)
2338
   {
2339
      bool allow;
2340
      TestCaseGridRowChanging(Sender, 0, 1, allow = true);
2341
   }
2342
}
2343
 
2344
// Add a New Use Case
2345
 
2346
void __fastcall TMainForm::AddTestCaseNodeClick(TObject *Sender)
2347
{
2348
    TADOQuery  *query = new TADOQuery(this);
2349
    AnsiString sql_statement;
2350
    query->Connection = Data_Module->IntegrationDBConnection;
2351
 
2352
    try
2353
    {
2354
        Data_Module->IntegrationDBConnection->BeginTrans();
2355
 
2356
        sql_statement="";
2357
        sql_statement.sprintf("SELECT MAX(TESTCASE_SEQNO) MAX_SEQNO FROM TEST_SCENARIOS "
2358
                       "WHERE PROJECT_CODE='%s' AND ITERATION=%d "
2359
                              "AND TESTCASE_ID='%s'",
2360
                              m_currentproject.c_str(),
2361
                              m_currentiteration,
2362
                              m_currenttestcaseid.c_str());
2363
 
2364
        query->SQL->Text = sql_statement;
2365
        query->Open();
2366
        int max_testcase_seqno = query->FieldByName("MAX_SEQNO")->AsInteger;
2367
 
2368
        sql_statement="";
2369
        sql_statement.sprintf("INSERT INTO TEST_SCENARIOS (PROJECT_CODE,ITERATION,USECASE,TESTCASE_ID,TESTCASE_SEQNO) "
2370
                              "VALUES ('%s',%d,'%s','%s',%d) ",
2371
                              m_currentproject.c_str(),
2372
                              m_currentiteration,
2373
                              m_currenttestcaseid.c_str(),
2374
                              m_currenttestcaseid.c_str(),
2375
                              max_testcase_seqno+1);
2376
 
2377
        query->SQL->Text = sql_statement;
2378
        query->ExecSQL();
2379
 
2380
        Data_Module->IntegrationDBConnection->CommitTrans();
2381
    }
2382
    catch(...)
2383
    {
2384
        Data_Module->IntegrationDBConnection->RollbackTrans();
2385
    }
2386
 
2387
    delete query;
2388
 
2389
   //refresh query and the tree view
2390
   TxnStepsQuery->Refresh();   
2391
   bool allow;
2392
   TestCaseGridRowChanging(Sender, 0, 1, allow = true);
2393
}
2394
//---------------------------------------------------------------------------
2395
 
2396
void __fastcall TMainForm::TestCaseTreeViewEndDrag(TObject *Sender,
2397
      TObject *Target, int X, int Y)
2398
{
2399
    TTreeNode* target_node = TestCaseTreeView->GetNodeAt(X, Y);
2400
    if ((target_node != NULL) && (target_node != m_startnode))
2401
    {
2402
        TTreeNode *new_node         = NULL;
2403
        TTreeNode *target_case_node = NULL;
2404
        TTreeNode *start_case_node  = NULL;
2405
        bool isStartTestCase        = (m_startnode->Level == 0);
2406
        bool isTargetTestCase       = (target_node->Level == 0);
2407
 
2408
        // Move the selected transaction
2409
 
2410
        start_case_node = isStartTestCase ? m_startnode : m_startnode->Parent;
2411
        target_case_node = isTargetTestCase ? target_node : target_node->Parent;
2412
 
2413
        TestCaseTreeView->Items->BeginUpdate();
2414
 
2415
        new_node = (isStartTestCase) ?
2416
                    TestCaseTreeView->Items->Insert(target_case_node, m_startnode->Text) :
2417
                    TestCaseTreeView->Items->AddChild(target_case_node, m_startnode->Text);
2418
 
2419
        new_node->Data = m_startnode->Data;
2420
        TestCaseTreeView->Items->Delete(m_startnode);
2421
        m_startnode = NULL;
2422
 
2423
        TestCaseTreeView->Items->EndUpdate();
2424
 
2425
        // Refresh the tree, resequencing affected cases/transactions
2426
 
2427
      if (isStartTestCase)
2428
        {
2429
            bool allow;
2430
            ResequenceTestCases(target_case_node);
2431
            TestCaseGridRowChanging(Sender, 0, 1, allow = true);
2432
        }
2433
        else
2434
        {
2435
            ResequenceTransactions(target_case_node);
2436
            LoadTestCaseNodes(target_case_node);
2437
            if( start_case_node != target_case_node )
2438
            {
2439
                ResequenceTransactions(start_case_node);
2440
                LoadTestCaseNodes(start_case_node);
2441
            }
2442
        }
2443
    }
2444
}
2445
//---------------------------------------------------------------------------
2446
 
2447
void __fastcall TMainForm::ResequenceTestCases(TTreeNode *testcase_node)
2448
{
2449
    // Resequence Subtree nodes
2450
    TADOQuery  *query = new TADOQuery(this);
2451
    AnsiString sql_statement;
2452
    query->Connection = Data_Module->IntegrationDBConnection;
2453
 
2454
    try
2455
    {
2456
        Data_Module->IntegrationDBConnection->BeginTrans();
2457
 
2458
        int testcaseseqno = 1;
2459
        for (int i=0; i<TestCaseTreeView->Items->Count; i++)
2460
        {
2461
            TTreeNode*  childnode = TestCaseTreeView->Items->Item[i];
2462
 
2463
            if (childnode->Level == 0) // Only consider TestCase Nodes
2464
            {
2465
                int        testscenario_no = (int)(childnode->Data);
2466
 
2467
                sql_statement="";
2468
                sql_statement.sprintf("UPDATE TEST_SCENARIOS SET TESTCASE_SEQNO=%d "
2469
                                      "WHERE TESTSCENARIO_NO=%d",
2470
                                      testcaseseqno,
2471
                                      testscenario_no);
2472
 
2473
                query->SQL->Text = sql_statement;
2474
                query->ExecSQL();
2475
 
2476
                testcaseseqno++;
2477
            }
2478
        }
2479
 
2480
      Data_Module->IntegrationDBConnection->CommitTrans();
2481
    }
2482
    catch(...)
2483
    {
2484
        Data_Module->IntegrationDBConnection->RollbackTrans();
2485
    }
2486
 
2487
    delete query;
2488
}
2489
 
2490
//---------------------------------------------------------------------------
2491
 
2492
void __fastcall TMainForm::ResequenceTransactions(TTreeNode *testcase_node)
2493
{
2494
    // Resequence Subtree nodes
2495
    TADOQuery  *query = new TADOQuery(this);
2496
    AnsiString sql_statement;
2497
    query->Connection = Data_Module->IntegrationDBConnection;
2498
 
2499
    try
2500
    {
2501
        Data_Module->IntegrationDBConnection->BeginTrans();
2502
 
2503
        int testscenario_no = (int)(testcase_node->Data);
2504
 
2505
        for (int i=0; i<testcase_node->Count; i++)
2506
        {
2507
            sql_statement="";
2508
            sql_statement.sprintf("UPDATE TRANSACTION_SPECIFICATION SET SEQ_NO=%d, TESTSCENARIO_NO=%d"
2509
                                  "WHERE PROJECT_CODE='%s' AND ITERATION=%d "
2510
                                  "AND TXNSPEC_NO=%d",
2511
                                  i+1,
2512
                                  testscenario_no,                                  
2513
                                  m_currentproject.c_str(),
2514
                                  m_currentiteration,
2515
                                  testcase_node->Item[i]->Data);
2516
 
2517
            query->SQL->Text = sql_statement;
2518
            query->ExecSQL();
2519
        }
2520
 
2521
        Data_Module->IntegrationDBConnection->CommitTrans();
2522
    }
2523
    catch(...)
2524
    {
2525
        Data_Module->IntegrationDBConnection->RollbackTrans();
2526
    }
2527
 
2528
    delete query;
2529
}
2530
 
2531
//---------------------------------------------------------------------------
2532
void __fastcall TMainForm::TestCaseTreeViewStartDrag(TObject *Sender,
2533
      TDragObject *&DragObject)
2534
{
2535
   m_startnode = TestCaseTreeView->Selected;
2536
}
2537
//---------------------------------------------------------------------------
2538
 
2539
void __fastcall TMainForm::TestCaseTreeViewDragOver(TObject *Sender,
2540
      TObject *Source, int X, int Y, TDragState State, bool &Accept)
2541
{
2542
    Accept = false;
2543
 
2544
    TTreeView * tree_view = dynamic_cast<TTreeView *>(Source);
2545
    if ( (tree_view != NULL) &&
2546
         (tree_view == TestCaseTreeView) )
2547
    {
2548
        TTreeNode * source_node = TestCaseTreeView->GetNodeAt(X, Y);
2549
        if( source_node != NULL )
2550
        {
2551
            // Source and destination cannot be the same
2552
            if( m_startnode == source_node )
2553
                return;
2554
 
2555
            // Test scenarios cannot be dropped on test cases
2556
            if( (m_startnode->Level == 0) &&
2557
                (source_node->Level == 1) )
2558
                return;
2559
 
2560
            // Otherwise we can drop here
2561
            Accept = true;
2562
        }
2563
    }
2564
}
2565
//---------------------------------------------------------------------------
2566
 
2567
void __fastcall TMainForm::ApplyTemplatesClick(TObject *Sender)
2568
{
2569
   const TCursor Save_Cursor = Screen->Cursor;
2570
   try
2571
   {
2572
      Screen->Cursor = crHourGlass;
2573
      try
2574
      {
2575
         TADOQuery * query = 0;
2576
         try
2577
         {
2578
            const unsigned count = countTransactionsInIteration(
2579
               m_currentproject.c_str(),
2580
               m_currentiteration );
2581
            m_progressBar->open( count * 2 + 1 );
2582
 
2583
            // Rebuild the transaction templates, they may have changed.
2584
            buildTransactionTemplates(
2585
               m_transactionTemplates,
2586
               m_currentproject,
2587
               m_currentiteration );
2588
            m_progressBar->increment();
2589
 
2590
            buildTransactionsForIteration(
2591
               m_transactionCache,
2592
               *m_progressBar,
2593
               m_schema_handle,
2594
               m_currentproject.c_str(),
2595
               m_currentiteration );
2596
 
2597
            query = new TADOQuery( this );
2598
            query->Connection = Data_Module->IntegrationDBConnection;
2599
 
2600
            AnsiString sqlStatement;
2601
            sqlStatement.sprintf(
2602
               "SELECT "
2603
                  "TESTSCENARIO_NO "
2604
                  ""
2605
               "FROM "
2606
                  "TEST_SCENARIOS "
2607
               "WHERE "
2608
                  "PROJECT_CODE=\'%s\' AND "
2609
                  "ITERATION=%d",
2610
               m_currentproject.c_str(),
2611
               m_currentiteration );
2612
            query->SQL->Text = sqlStatement;
2613
            query->Open();
2614
 
2615
            try
2616
            {
2617
               Data_Module->IntegrationDBConnection->BeginTrans();
2618
               while ( !query->Eof )
2619
               {
2620
                  applyTemplatesToScenario(
2621
                     *m_progressBar,
2622
                     query->FieldByName( "TESTSCENARIO_NO" )->AsInteger );
2623
                  query->Next();
2624
               }
2625
               Data_Module->IntegrationDBConnection->CommitTrans();
2626
 
2627
               if ( TxnValuesQuery->State != dsInactive )
2628
               {
2629
                  TxnValuesQuery->Refresh();
2630
                  HeaderStructureGrid->Invalidate();
2631
               }
2632
               if ( TxnHeaderValuesQuery->State != dsInactive )
2633
               {
2634
                  TxnHeaderValuesQuery->Refresh();
2635
                  TransactionValueGrid->Invalidate();
2636
               }
2637
 
2638
            }
2639
            catch ( ... )
2640
            {
2641
               Data_Module->IntegrationDBConnection->RollbackTrans();
2642
               throw;
2643
            }
2644
         }
2645
         __finally
2646
         {
2647
            delete query;
2648
            query = 0;
2649
 
2650
            m_progressBar->close();
2651
         }
2652
      }
2653
      catch ( const std::exception & exception )
2654
      {
2655
         MessageDlg(
2656
            exception.what(),
2657
            mtError, TMsgDlgButtons() << mbOK, 0 );
2658
      }
2659
      catch ( ... )
2660
      {
2661
         MessageDlg(
2662
            "Unknown exception applying templates to this scenario.",
2663
            mtError, TMsgDlgButtons() << mbOK, 0 );
2664
      }
2665
   }
2666
   __finally
2667
   {
2668
      Screen->Cursor = Save_Cursor;
2669
   }
2670
}
2671
//---------------------------------------------------------------------------
2672
 
2673
void __fastcall TMainForm::InitialiseMASSTxns()
2674
{
2675
   AnsiString  sql_statement;
2676
 
2677
   TADOQuery   *query = new TADOQuery(this);
2678
    query->Connection = Data_Module->IntegrationDBConnection;
2679
 
2680
   m_mass_txns.clear();
2681
 
2682
   try
2683
    {
2684
        sql_statement="";
2685
        sql_statement.sprintf("SELECT NAME,UDTYPE,UDSUBTYPE "
2686
                              "FROM MASS_TXNS "
2687
                              "WHERE PROJECTCODE='%s' "
2688
                              "AND   ITERATION=%d "
2689
                       "AND   ENABLED = 'Y' ",
2690
                              m_currentproject.c_str(),
2691
                              m_currentiteration);
2692
 
2693
        query->SQL->Text = sql_statement;
2694
        query->Open();
2695
        while (!query->Eof)
2696
        {
2697
            unsigned short udtype      = query->FieldByName("UDTYPE")->AsInteger;
2698
            unsigned short udsubtype   = query->FieldByName("UDSUBTYPE")->AsInteger;
2699
            unsigned int   udindex  = (udtype << 16) + udsubtype;
2700
 
2701
            TXNIndexPair   pair(udindex, query->FieldByName("NAME")->AsString);
2702
 
2703
            m_mass_txns.insert(pair);
2704
 
2705
            query->Next();
2706
        }
2707
    }
2708
    __finally
2709
    {
2710
      delete query;
2711
    }
2712
}
2713
 
2714
//---------------------------------------------------------------------------
2715
 
2716
void __fastcall TMainForm::InitialiseTxnParams(unsigned int schema_format_version, IterationParams &iteration_params, IterationSequences &iteration_sequences)
2717
{
2718
   AnsiString  sql_statement;
2719
 
2720
    // Format Version only encodes Major/Minor numbers, and not Patch Level
2721
   AnsiString  formatversion;
2722
    formatversion.sprintf("0x%08X", schema_format_version);
2723
 
2724
    IterationParamsPair    pair("#0_@FORMATVERSION", formatversion.c_str());
2725
    iteration_params.insert(pair);
2726
 
2727
    TADOQuery  *query = new TADOQuery(this);
2728
    query->Connection = Data_Module->IntegrationDBConnection;
2729
 
2730
    TADOQuery  *seqquery = new TADOQuery(this);
2731
    seqquery->Connection = Data_Module->IntegrationDBConnection;
2732
 
2733
    try
2734
    {
2735
        sql_statement="";
2736
        sql_statement.sprintf("SELECT * FROM ITERATION_PARAMS "
2737
                              "WHERE PROJECT_CODE='%s' AND ITERATION=%d AND SUPPORTED <> 0 " ,
2738
                              m_currentproject.c_str(), m_currentiteration);
2739
 
2740
        query->SQL->Text = sql_statement;
2741
        query->Open();
2742
        while (!query->Eof)
2743
        {
2744
            int         testscenario_no = 0;
2745
 
2746
            string      fieldvalue  = query->FieldByName("FIELDVALUE")->AsString.c_str();
2747
 
2748
            if ( !query->FieldByName("TESTSCENARIO_NO")->IsNull )
2749
            {
2750
                testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger;
2751
            }
2752
 
2753
            // Format is: @SEQ(<name>,<start>,<inc>,<limit>)
2754
            if (fieldvalue.substr(0,4) == "@SEQ")
2755
            {
2756
                int lpos = fieldvalue.find("(")+1;
2757
                int rpos = fieldvalue.rfind(")");
2758
 
2759
                string  seqargs = fieldvalue.substr( lpos, rpos );
2760
                string  seqname;
2761
                string  seqstart;
2762
                string  seqinc;
2763
                string  seqlimit;
2764
 
2765
                const char *p = seqargs.c_str();
2766
                while ( (*p != '\0') && (*p == ' ') ) p++;     // Skip Whitespace
2767
 
2768
                while ( (*p != '\0') && (*p != ',') && (*p != ' ') )
2769
                {
2770
                    seqname += *p;
2771
                    p++;
2772
                }
2773
                if (*p != '\0') p++;
2774
 
2775
                while ( (*p != '\0') && (*p == ' ') )
2776
                {
2777
                    p++;      // Skip Whitespace
2778
                }
2779
                while ( (*p != '\0') && (*p != ',') && (*p != ' ') )
2780
                {
2781
                    seqstart += *p;
2782
                    p++;
2783
                }
2784
                if (*p != '\0') p++;
2785
 
2786
                while ( (*p != '\0') && (*p == ' ') )
2787
                {
2788
                    p++;      // Skip Whitespace
2789
                }
2790
 
2791
                while ( (*p != '\0') && (*p != ',') && (*p != ' ') )
2792
                {
2793
                    seqinc += *p;
2794
                    p++;
2795
                }
2796
                if (*p != '\0') p++;
2797
 
2798
                while ( (*p != '\0') && (*p == ' ') )
2799
                {
2800
                    p++;      // Skip Whitespace
2801
                }
2802
 
2803
                while (*p != '\0')
2804
                {
2805
                    seqlimit += *p;
2806
                    p++;
2807
                }
2808
 
2809
                IterationSequence   sequence;
2810
                sequence.name    = seqname;
2811
 
2812
                if (seqstart.length() > 0)
2813
                {
2814
                    sequence.initial_value = atoi(seqstart.c_str());
2815
                }
2816
                else
2817
                {
2818
                    sequence.initial_value = 0;
2819
                }
2820
 
2821
                if (seqname[0] == '#')
2822
                {
2823
                    string seqgenname = seqname.substr(1,seqname.length()-1);
2824
 
2825
                    sql_statement="";
2826
                    sql_statement.sprintf("SELECT SEQVALUE FROM SEQGEN WHERE PROJECT_CODE='%s' AND ITERATION=%d AND SEQNAME='%s'",
2827
                                          m_currentproject.c_str(),
2828
                                          m_currentiteration,
2829
                                          seqgenname.c_str()
2830
                                          );
2831
                    seqquery->SQL->Text = sql_statement;
2832
                    seqquery->Open();
2833
                    if (seqquery->RecordCount == 0)
2834
                    {
2835
                        sql_statement="";
2836
                        sql_statement.sprintf("INSERT INTO SEQGEN (PROJECT_CODE,ITERATION,SEQNAME,SEQVALUE) VALUES ('%s',%d,'%s',%d)",
2837
                                              m_currentproject.c_str(),
2838
                                              m_currentiteration,
2839
                                              seqgenname.c_str(),
2840
                                              sequence.initial_value
2841
                                              );
2842
                        seqquery->SQL->Text = sql_statement;
2843
                        seqquery->ExecSQL();
2844
                    }
2845
                    else
2846
                    {
2847
                        sequence.initial_value = seqquery->FieldByName("SEQVALUE")->AsInteger;
2848
                    }
2849
                }
2850
 
2851
                sequence.value = sequence.initial_value;
2852
 
2853
                if (seqinc.length() > 0)
2854
                {
2855
                    sequence.increment    = atoi(seqinc.c_str());
2856
                }
2857
                else
2858
                {
2859
                    sequence.increment    = 1;
2860
                }
2861
 
2862
                if (seqlimit.length() > 0)
2863
                {
2864
                    sequence.reset_at  = atoi(seqlimit.c_str());
2865
                }
2866
                else
2867
                {
2868
                    sequence.reset_at  = 0;
2869
                }
2870
 
2871
                sequence.reset_at = 0;
2872
 
2873
                IterationSequencesPair seqpair(sequence.name, sequence);
2874
                iteration_sequences.insert(seqpair);
2875
            }
2876
 
2877
            AnsiString  param_name;
2878
            param_name.sprintf("#%d_%s", testscenario_no, query->FieldByName("NAME")->AsString.c_str());
2879
 
2880
            IterationParamsPair  pair2(param_name.c_str(), fieldvalue.c_str());
2881
            iteration_params.insert(pair2);
2882
 
2883
            query->Next();
2884
        }
2885
    }
2886
    __finally
2887
    {
2888
        delete query;
2889
        delete seqquery;
2890
    }
2891
}
2892
 
2893
//---------------------------------------------------------------------------
2894
 
2895
void __fastcall TMainForm::InitialiseTestScenario(unsigned int testscenario_no, TxnSpecValueMap &txnSpecValueMap, FoundTxnSpecValueMap &foundTxnSpecValueMap, IterationSequences &iteration_sequences, IterationParams &iteration_params)
2896
{
2897
   AnsiString  sql_statement;
2898
   TADOQuery  *query = new TADOQuery(this);
2899
   query->Connection = Data_Module->IntegrationDBConnection;
2900
 
2901
   TADOQuery  *values_query = new TADOQuery(this);
2902
   values_query->Connection = Data_Module->IntegrationDBConnection;
2903
 
2904
   try
2905
   {
2906
      sql_statement="";
2907
      sql_statement.sprintf("select txnspec_no,udtype,udsubtype "
2908
                       "from transaction_specification "
2909
                       "where testscenario_no=%d order by seq_no",
2910
                              testscenario_no);
2911
      query->SQL->Text = sql_statement;
2912
      query->Open();
2913
      while (!query->Eof)
2914
      {
2915
          // For each transaction
2916
          unsigned int   txnspec_no  = query->FieldByName("TXNSPEC_NO")->AsInteger;
2917
          unsigned short  udtype     = query->FieldByName("UDTYPE")->AsInteger;
2918
          unsigned short  udsubtype  = query->FieldByName("UDSUBTYPE")->AsInteger;
2919
          unsigned int   udindex  = (udtype << 16) + udsubtype;
2920
 
2921
          TXNIndexMap::iterator   txn_itr = m_mass_txns.find(udindex);
2922
 
2923
          if (txn_itr != m_mass_txns.end())
2924
          {
2925
             string   structure_name;
2926
             string   structure_handle;
2927
 
2928
             structure_name = (*txn_itr).second.c_str();
2929
 
2930
             // Create a Transaction Instance
2931
             if (XMLSchema->Create(m_schema_handle.c_str(), structure_name.c_str(), m_currentiteration, structure_handle, NULL))
2932
             {
2933
                ProcessTxnStructure(structure_handle, udtype, udsubtype, testscenario_no, txnspec_no, values_query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, 0);
2934
                XMLSchema->Destroy(structure_handle);
2935
             }
2936
             else
2937
             {
2938
                AnsiString  msg;
2939
                msg.sprintf("Failed to create schema object for Schema: '%s' Structure: '%s'",
2940
                        m_schema_handle.c_str(),
2941
                        structure_name.c_str());
2942
                MessageDlg(msg,
2943
                        mtError, TMsgDlgButtons() << mbOK, 0);
2944
             }
2945
 
2946
          } // Found Transaction declaration in MASS TXNS
2947
 
2948
          query->Next();
2949
      }
2950
   }
2951
   __finally
2952
   {
2953
      delete query;
2954
      delete values_query;
2955
   }
2956
}
2957
 
2958
//---------------------------------------------------------------------------
2959
 
2960
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)
2961
{
2962
   vector<string>          structure_attributes;
2963
    vector<string>::iterator  s_itr;
2964
    AnsiString             sql_statement;
2965
 
2966
    XMLSchema->GetAttributes(structure_handle, structure_attributes);
2967
 
2968
    s_itr = structure_attributes.begin();
2969
    while (s_itr != structure_attributes.end())
2970
    {
2971
      string   attribute_handle = (*s_itr);
2972
 
2973
      string   elementtype;
2974
 
2975
        XMLSchema->GetAttributeProperty(attribute_handle, "type", elementtype);
2976
 
2977
        if (elementtype == "field")
2978
        {
2979
            string   datatype;
2980
 
2981
            XMLSchema->GetAttributeProperty(attribute_handle, "datatype", datatype);
2982
 
2983
            if (datatype == "Struct")
2984
            {
2985
                ProcessTxnStructure(attribute_handle, udtype, udsubtype, testscenario_no, txnspec_no, query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, 0);
2986
            }
2987
            else
2988
            {
2989
               string   fieldname;
2990
                string  tagvalue;
2991
                string  xpath;
2992
 
2993
                XMLSchema->GetAttributeProperty(attribute_handle, "tag", tagvalue);
2994
 
2995
                if (tagvalue.length() > 0)
2996
                {
2997
                    XMLSchema->GetAttributeProperty(attribute_handle, "name", fieldname);
2998
                    XMLSchema->GetAttributeProperty(attribute_handle, "xpath", xpath);
2999
 
3000
                    AnsiString   lookup_fieldname;
3001
                    AnsiString   display_fieldname;
3002
 
3003
                    if (nested_subscript == 0)
3004
                    {
3005
                       lookup_fieldname.sprintf("$%s", fieldname.c_str());
3006
                       display_fieldname = fieldname.c_str();
3007
                    }
3008
                    else
3009
                    {
3010
                      lookup_fieldname.sprintf("$%s#%d", fieldname.c_str(), nested_subscript);
3011
                      display_fieldname.sprintf("%s#%d", fieldname.c_str(), nested_subscript);
3012
                    }
3013
 
3014
                    AnsiString   field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, lookup_fieldname.c_str(), udtype, udsubtype);
3015
 
3016
                    AnsiString   key;
3017
 
3018
                    if (nested_subscript == 0)
3019
                    {
3020
                        key.sprintf("%d_%d_%s",
3021
                                    testscenario_no,
3022
                                    txnspec_no,
3023
                                    fieldname.c_str());
3024
                    }
3025
                    else
3026
                    {
3027
                        key.sprintf("%d_%d_%s#%d",
3028
                                    testscenario_no,
3029
                                    txnspec_no,
3030
                                    fieldname.c_str(),
3031
                                    nested_subscript);
3032
                    }
3033
 
3034
                    FoundTxnSpecValuePair   foundpair(key, 0);
3035
                    foundTxnSpecValueMap.insert(foundpair);
3036
 
3037
                    TxnSpecValueIterator  txnspec_value_itr = txnSpecValueMap.find(key);
3038
                    TxnSpecValue       &existing_value = (*txnspec_value_itr).second;
3039
 
3040
                    // Either no existing entry OR the current entry is NOT User supplied
3041
                    // (ie. Ignore field values for existing user supplied items)
3042
                    if ( (txnspec_value_itr == txnSpecValueMap.end()) ||
3043
                      (existing_value.user_supplied == 'N') )
3044
                    {
3045
                       if ( (existing_value.fieldtag  != atoi(tagvalue.c_str()) ||
3046
                         (existing_value.fieldvalue   != field_value) ||
3047
                         (existing_value.xpath     != AnsiString(xpath.c_str()))) )
3048
                       {
3049
                           // Remove the existing value
3050
                           if (txnspec_value_itr != txnSpecValueMap.end())
3051
                           {
3052
                              sql_statement="";
3053
                                sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES WHERE "
3054
                                                      "TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d AND FIELDNAME='%s'",
3055
                                                      testscenario_no,
3056
                                         txnspec_no,
3057
                                                      fieldname.c_str() );
3058
                                query->SQL->Text = sql_statement;
3059
                                query->ExecSQL();
3060
                           }
3061
 
3062
                           // Add the new value
3063
                           sql_statement="";
3064
                           if (field_value.Length() > 0)
3065
                           {
3066
                              sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, FIELDVALUE, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, XPATH, SUBSCRIPT, USER_SUPPLIED) "
3067
                                                      "VALUES (%s,'%s',%d,%d,'%s','%s','%s',%d,'N')",
3068
                                                      tagvalue.c_str(),
3069
                                                      field_value.c_str(),
3070
                                                      testscenario_no,
3071
                                                      txnspec_no,
3072
                                                      fieldname.c_str(),
3073
                                                      display_fieldname.c_str(),
3074
                                                      xpath.c_str(),
3075
                                                      nested_subscript);
3076
                           }
3077
                           else
3078
                           {
3079
                              sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, XPATH, SUBSCRIPT, USER_SUPPLIED) "
3080
                                                      "VALUES (%s,%d,%d,'%s','%s','%s',%d,'N')",
3081
                                                      tagvalue.c_str(),
3082
                                                      testscenario_no,
3083
                                                      txnspec_no,
3084
                                                      fieldname.c_str(),
3085
                                                      display_fieldname.c_str(),
3086
                                                      xpath.c_str(),
3087
                                                      nested_subscript);
3088
                           }
3089
 
3090
                           query->SQL->Text = sql_statement;
3091
                           query->ExecSQL();
3092
                        }
3093
                    }
3094
                }
3095
           }
3096
      }
3097
      else
3098
      if (elementtype == "repeat")
3099
      {
3100
         string refcountfield;
3101
         string   maxOccursStr;
3102
         string   refcountAttribute;
3103
 
3104
         XMLSchema->GetAttributeProperty(attribute_handle, "refcountfield", refcountfield);
3105
 
3106
         if (!refcountfield.empty())
3107
         {
3108
             string      refcountAttribute = structure_handle+"."+refcountfield;
3109
 
3110
             XMLSchema->GetAttributeProperty(refcountAttribute, "max", maxOccursStr);
3111
         }
3112
 
3113
         if (maxOccursStr.empty())
3114
         {
3115
             XMLSchema->GetAttributeProperty(attribute_handle, "maxOccurs", maxOccursStr);
3116
         }
3117
 
3118
         int maxOccurs = atoi(maxOccursStr.c_str());
3119
 
3120
         // Limit to 100 elements
3121
         if (maxOccurs > 100)
3122
         {
3123
             maxOccurs = 100;
3124
         }
3125
 
3126
        string   repeat_name;
3127
        XMLSchema->GetAttributeProperty(attribute_handle, "name", repeat_name);
3128
 
3129
        XMLSchema->SetAttributeValue(structure_handle, refcountfield, maxOccurs);
3130
 
3131
        for (int occurrence=1; occurrence<=maxOccurs; occurrence++)
3132
        {
3133
            string      repeat_attribute_handle;
3134
            AnsiString temp;
3135
 
3136
            temp.sprintf("%s.%d.%s",attribute_handle.c_str(),occurrence,repeat_name.c_str());
3137
 
3138
            repeat_attribute_handle = temp.c_str();
3139
 
3140
            string  repeat_attribute_datatype;
3141
            XMLSchema->GetAttributeProperty(repeat_attribute_handle, "datatype", repeat_attribute_datatype);
3142
 
3143
            if (repeat_attribute_datatype != "Struct")
3144
            {
3145
                string fieldname;
3146
                string xpath;
3147
                string tagvalue;
3148
 
3149
                XMLSchema->GetAttributeProperty(repeat_attribute_handle, "tag", tagvalue);
3150
 
3151
                if (tagvalue.length() > 0)
3152
                {
3153
                     XMLSchema->GetAttributeProperty(repeat_attribute_handle, "name", fieldname);
3154
                     XMLSchema->GetAttributeProperty(repeat_attribute_handle, "xpath", xpath);
3155
 
3156
                     string   lookup_fieldname = "$"+fieldname;
3157
                     AnsiString  field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, lookup_fieldname, udtype, udsubtype);
3158
 
3159
                     AnsiString  key;
3160
 
3161
                     key.sprintf("%d_%d_%s.%d",
3162
                                 testscenario_no,
3163
                                 txnspec_no,
3164
                                 fieldname.c_str(),
3165
                                 occurrence);
3166
 
3167
                     FoundTxnSpecValuePair   foundpair(key, 0);
3168
                     foundTxnSpecValueMap.insert(foundpair);
3169
 
3170
                     TxnSpecValueIterator txnspec_value_itr = txnSpecValueMap.find(key);
3171
                     TxnSpecValue         &existing_value = (*txnspec_value_itr).second;
3172
 
3173
                     // Either no existing entry OR the current entry is NOT User supplied
3174
                     // (ie. Ignore field values for existing user supplied items)
3175
                     if ( (txnspec_value_itr == txnSpecValueMap.end()) ||
3176
                          (existing_value.user_supplied == 'N') )
3177
                     {
3178
                         if ( (existing_value.fieldtag   != atoi(tagvalue.c_str()) ||
3179
                              (existing_value.fieldvalue != field_value) ||
3180
                              (existing_value.xpath      != AnsiString(xpath.c_str()))) )
3181
                         {
3182
                             // Remove the existing value
3183
                             if (txnspec_value_itr != txnSpecValueMap.end())
3184
                             {
3185
                                 sql_statement="";
3186
                                 sql_statement.sprintf("DELETE FROM TXNSPEC_VALUES WHERE "
3187
                                         "TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d AND FIELDNAME='%s' AND SUBSCRIPT=%d",
3188
                                                       testscenario_no,
3189
                                                       txnspec_no,
3190
                                                       fieldname.c_str(),
3191
                                                       occurrence );
3192
                                 query->SQL->Text = sql_statement;
3193
                                 query->ExecSQL();
3194
                             }
3195
 
3196
                             AnsiString   subscripted_fieldname;
3197
                             subscripted_fieldname.sprintf("%s#%d", fieldname.c_str(), occurrence);
3198
 
3199
                             // Add the new value
3200
                             sql_statement="";
3201
                             if (field_value.Length() > 0)
3202
                             {
3203
                                 sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, FIELDVALUE, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, SUBSCRIPT, XPATH, USER_SUPPLIED) "
3204
                                                       "VALUES (%s,'%s',%d,%d,'%s','%s',%d,'%s','N')",
3205
                                                       tagvalue.c_str(),
3206
                                                       field_value.c_str(),
3207
                                                       testscenario_no,
3208
                                                       txnspec_no,
3209
                                                       fieldname.c_str(),
3210
                                                       subscripted_fieldname.c_str(),
3211
                                                       occurrence,
3212
                                                       xpath.c_str());
3213
                             }
3214
                             else
3215
                             {
3216
                                 sql_statement.sprintf("INSERT INTO TXNSPEC_VALUES(FIELDTAG, TESTSCENARIO_NO, TXNSPEC_NO, FIELDNAME, DISPLAY_FIELDNAME, SUBSCRIPT, XPATH, USER_SUPPLIED) "
3217
                                                       "VALUES (%s,%d,%d,'%s','%s',%d,'%s','N')",
3218
                                                       tagvalue.c_str(),
3219
                                                       testscenario_no,
3220
                                                       txnspec_no,
3221
                                                       fieldname.c_str(),
3222
                                                       subscripted_fieldname.c_str(),
3223
                                                       occurrence,
3224
                                         xpath.c_str());
3225
                             }
3226
 
3227
                             query->SQL->Text = sql_statement;
3228
                             query->ExecSQL();
3229
                            }
3230
                        }
3231
                    } // if (tagvalue.length() > 0)
3232
                } // if (repeat_attribute_datatype != "Struct")
3233
                else
3234
                {
3235
                  ProcessTxnStructure(repeat_attribute_handle, udtype, udsubtype, testscenario_no, txnspec_no, query, txnSpecValueMap, foundTxnSpecValueMap, iteration_params, iteration_sequences, occurrence);
3236
                }
3237
            } // for (int i=1; i<=occurrence; i++)
3238
        }
3239
 
3240
        s_itr++;
3241
    } // while
3242
}
3243
 
3244
//---------------------------------------------------------------------------
3245
 
3246
AnsiString TMainForm::LookupParameter(IterationParams &iteration_params, IterationSequences &iteration_sequences, TADOQuery *query, int testscenario_no, const string &param, unsigned short udtype, unsigned short udsubtype)
3247
{
3248
   AnsiString  field_value;
3249
   AnsiString  param_lookup;
3250
 
3251
    param_lookup.sprintf("#%d_%s", testscenario_no, param.c_str());
3252
 
3253
    IterationParams::iterator  param_itr = iteration_params.find(param_lookup.c_str());
3254
 
3255
    if (param_itr == iteration_params.end())
3256
    {
3257
      param_lookup="";
3258
       param_lookup.sprintf("#%d_%s", 0, param.c_str());
3259
       param_itr = iteration_params.find(param_lookup.c_str());
3260
    }
3261
 
3262
    if (param_itr != iteration_params.end())
3263
    {
3264
        string param_value = (*param_itr).second;
3265
 
3266
        if (param_value == "@FORMATVERSION")
3267
        {
3268
            field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, param_value, udtype, udsubtype);
3269
        }
3270
        else
3271
        if (param_value == "@NOW")
3272
        {
3273
            TDateTime   current_time = TDateTime::CurrentDateTime();
3274
 
3275
            field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy hh:nn:ss").c_str());
3276
        }
3277
        else
3278
        if (param_value == "@UTCNOW")
3279
        {
3280
            TDateTime   current_time = TDateTime::CurrentDateTime() + ((_timezone/3600.0)/24.0);
3281
 
3282
            field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy hh:nn:ss").c_str());
3283
        }
3284
        else
3285
        if (param_value == "@TODAY")
3286
        {
3287
            TDateTime   current_time = TDateTime::CurrentDateTime();
3288
 
3289
            field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy").c_str());
3290
        }
3291
        else
3292
        if (param_value == "@YESTERDAY")
3293
        {
3294
            TDateTime   current_time = TDateTime::CurrentDateTime() - 1;
3295
 
3296
            field_value.sprintf("%s", current_time.FormatString("dd-mm-yyyy").c_str());
3297
        }
3298
        else
3299
        if (param_value.substr(0,5) == "@RAND")
3300
        {
3301
         int   lpos = param_value.find("(")+1;
3302
 
3303
            string   rand_args = param_value.substr(lpos, param_value.rfind(")")-1);
3304
         string   lower_bound;
3305
         string   upper_bound;
3306
 
3307
            const char *p = rand_args.c_str();
3308
            while ( (*p != '\0') && (*p != ',') )
3309
            {
3310
               lower_bound += *p;
3311
 
3312
               p++;
3313
            }
3314
            if ( *p == ',' )
3315
            {
3316
               p++;
3317
            }
3318
            while ( (*p != '\0') && (*p != ')') )
3319
            {
3320
               upper_bound += *p;
3321
 
3322
               p++;
3323
            }
3324
 
3325
            int      lower_int = atoi(lower_bound.c_str());
3326
            int      upper_int = atoi(upper_bound.c_str());
3327
            double  rand_key = (double)rand() / (double)RAND_MAX;
3328
 
3329
            int   rand_value = (rand_key * (upper_int - lower_int)) + lower_int;
3330
 
3331
            field_value.sprintf("%d", rand_value);
3332
        }
3333
        else
3334
        if (param_value == "@UDTYPE")
3335
        {
3336
            field_value.sprintf("%d", udtype);
3337
        }
3338
      else
3339
        if (param_value == "@UDSUBTYPE")
3340
        {
3341
            field_value.sprintf("%d", udsubtype);
3342
        }
3343
        else
3344
        if (param_value == "@ACCOUNTTYPE")
3345
        {
3346
         int   account_format = 0;
3347
         switch(udtype)
3348
            {
3349
            case 1:  // Card
3350
               account_format = 2;
3351
                break;
3352
            case 2:  // Application
3353
               account_format = 1;
3354
                break;
3355
            case 3:  // Product
3356
               account_format = 3;
3357
                break;
3358
            case 4:  // Other
3359
               account_format = 4;
3360
                break;
3361
            case 5:  // Audit
3362
               account_format = 4;
3363
                break;
3364
            case 6:  // Event
3365
               account_format = 4;
3366
                break;
3367
            case 7:  // Project
3368
               account_format = 4;
3369
                break;
3370
            } // switch
3371
 
3372
            field_value.sprintf("%d", account_format);
3373
        }
3374
        else
3375
        if (param_value.substr(0,4) == "@SEQ")
3376
        {
3377
            int   lpos = param_value.find("(")+1;
3378
            int   comma_pos = param_value.find(",");
3379
            string   seqname = param_value.substr( lpos, comma_pos-lpos );
3380
 
3381
            IterationSequences::iterator s_itr = iteration_sequences.find( seqname );
3382
            if (s_itr != iteration_sequences.end())
3383
            {
3384
               IterationSequence &sequence = (*s_itr).second;
3385
 
3386
                field_value.sprintf("%d", sequence.value);
3387
                sequence.value += sequence.increment;
3388
 
3389
                if (sequence.reset_at != 0)
3390
                {
3391
                    if (sequence.value >= sequence.reset_at)
3392
                    {
3393
                        sequence.value = sequence.initial_value;
3394
                    }
3395
                }
3396
 
3397
                if (seqname[0] == '#')
3398
                {
3399
                    AnsiString   sql_statement;
3400
                    string    seqgenname = seqname.substr(1,seqname.length()-1);
3401
 
3402
                    sql_statement.sprintf("UPDATE SEQGEN SET SEQVALUE=%d where PROJECT_CODE='%s' AND ITERATION=%d AND SEQNAME='%s'",
3403
                                   sequence.value,
3404
                                          m_currentproject.c_str(),
3405
                                          m_currentiteration,
3406
                                          seqgenname.c_str()
3407
                                          );
3408
                    query->SQL->Text = sql_statement;
3409
                    query->ExecSQL();
3410
                }
3411
            }
3412
        }
3413
        else
3414
        if (param_value[0] == '@')
3415
        {
3416
            field_value = LookupParameter(iteration_params, iteration_sequences, query, testscenario_no, param_value, udtype, udsubtype);
3417
        }
3418
        else
3419
        {
3420
            field_value.sprintf("%s", param_value.c_str());
3421
        }
3422
    }
3423
    return field_value;
3424
}
3425
 
3426
//---------------------------------------------------------------------------
3427
 
3428
void __fastcall TMainForm::TxnHdrValuesQueryAfterInsert(TDataSet *DataSet)
3429
{
3430
   DataSet->FieldByName("PROJECT_CODE")->AsString  = m_currentproject;
3431
   DataSet->FieldByName("ITERATION")->AsInteger    = m_currentiteration;
3432
}
3433
//---------------------------------------------------------------------------
3434
 
3435
void __fastcall TMainForm::ScenarioParametersClick(TObject *Sender)
3436
{
3437
   ScenarioParamsForm->ShowForm(m_currentproject, m_currentiteration, m_testscenario_no);
3438
}
3439
//---------------------------------------------------------------------------
3440
 
3441
void __fastcall TMainForm::TestCaseTreeViewMouseDown(TObject *Sender,
3442
      TMouseButton Button, TShiftState Shift, int X, int Y)
3443
{
3444
   if (Button == mbRight)
3445
   {
3446
       TTreeNode* target_node = TestCaseTreeView->GetNodeAt(X, Y);
3447
       if (target_node != NULL)
3448
       {
3449
          target_node->Selected = true;
3450
       }
3451
   }
3452
}
3453
//---------------------------------------------------------------------------
3454
 
3455
void __fastcall TMainForm::TxnValuesQueryBeforePost(TDataSet *DataSet)
3456
{
3457
// DataSet->FieldByName( "USER_SUPPLIED" )->AsString = "Y";
3458
}
3459
//---------------------------------------------------------------------------
3460
 
3461
void __fastcall TMainForm::RemoveUserSuppliedValueClick(TObject *Sender)
3462
{
3463
   if (TxnValuesQuery->FieldByName("USER_SUPPLIED")->AsString == "Y")
3464
    {
3465
       Data_Module->IntegrationDBConnection->BeginTrans();
3466
 
3467
      TxnValuesQuery->Delete();
3468
 
3469
        Data_Module->IntegrationDBConnection->CommitTrans();
3470
    }
3471
}
3472
//---------------------------------------------------------------------------
3473
 
3474
void __fastcall TMainForm::CopyValuesToClipboardBtnClick(TObject *Sender)
3475
{
3476
    AnsiString clipboard_text;
3477
 
3478
    Clipboard()->Clear();
3479
 
3480
    AnsiString sql_statement;
3481
    TADOQuery  *query = new TADOQuery(this);
3482
    query->Connection = Data_Module->IntegrationDBConnection;
3483
 
3484
    sql_statement.sprintf("SELECT * FROM TXNSPEC_VALUES "
3485
                          "WHERE TESTSCENARIO_NO=%d AND TXNSPEC_NO=%d "
3486
                    "AND (FIELDVALUE IS NOT NULL OR FIELDVALUE<>'') "
3487
                          "ORDER BY FIELDNAME",
3488
                          m_testscenario_no, m_txnspec_no);
3489
 
3490
    query->SQL->Text = sql_statement;
3491
    query->Open();
3492
 
3493
    while (!query->Eof)
3494
    {
3495
        AnsiString  clipboard_line;
3496
 
3497
        clipboard_line.sprintf("%-30.30s\t%s\r\n",
3498
                        query->FieldByName("FIELDNAME")->AsString.c_str(),
3499
                        query->FieldByName("FIELDVALUE")->AsString.c_str()
3500
                               );
3501
 
3502
        clipboard_text += clipboard_line;
3503
 
3504
        query->Next();
3505
    }
3506
 
3507
   query->Close();
3508
 
3509
   Clipboard()->SetTextBuf( clipboard_text.c_str() );
3510
}
3511
//---------------------------------------------------------------------------
3512
 
3513
void __fastcall TMainForm::loadLegacyVariables( DefinedVariableTable & variables, const AnsiString & project, Iteration & iteration )
3514
{
3515
   TADOQuery * query = 0;
3516
   try
3517
   {
3518
      query = new TADOQuery( this );
3519
      query->Connection = Data_Module->IntegrationDBConnection;
3520
 
3521
      AnsiString sqlStatement;
3522
      sqlStatement.sprintf(
3523
         "SELECT "
3524
            "NAME,"
3525
            "FIELDVALUE,"
3526
            "TESTSCENARIO_NO "
3527
         "FROM "
3528
            "ITERATION_PARAMS "
3529
         "WHERE "
3530
            "PROJECT_CODE=\'%s\' AND "
3531
            "ITERATION=%d",
3532
         project.c_str(),
3533
         iteration.getIterationId() );
3534
      query->SQL->Text = sqlStatement;
3535
      query->Open();
3536
 
3537
      AnsiString        fieldName;
3538
      AnsiString        xpath;
3539
      AnsiString        value;
3540
      bool           qualified;
3541
      DefinedVariable * variable;
3542
      while ( !query->Eof )
3543
      {
3544
         fieldName   = query->FieldByName( "NAME" )->AsString;
3545
         value    = query->FieldByName( "FIELDVALUE" )->AsString;
3546
 
3547
         if ( !value.IsEmpty() )
3548
         {
3549
            if ( value[ 1 ] == '=' )
3550
            {
3551
               value.Delete( 1, 1 );
3552
            }
3553
 
3554
            if ( !value.IsEmpty() )
3555
            {
3556
               switch ( value[ 1 ] )
3557
               {
3558
               case '@':
3559
                  value[ 1 ] = '=';
3560
                  if ( FieldExpression::isFunctor(
3561
                        value.c_str() + 1 ) )
3562
                  {
3563
                     value += "()";
3564
                  }
3565
                  break;
3566
               default:
3567
                  break;
3568
               }
3569
            }
3570
         }
3571
 
3572
         if ( !fieldName.IsEmpty() )
3573
         {
3574
            qualified = !query->FieldByName( "TESTSCENARIO_NO" )->IsNull;
3575
 
3576
            switch ( fieldName[ 1 ] )
3577
            {
3578
            case '$':   // We don't worry about fields here.
3579
               break;
3580
            case '@':
3581
               if ( qualified )
3582
               {
3583
                  variable = &variables.defineVariable(
3584
                     fieldName.c_str() + 1,
3585
                     iteration.getTestScenario(
3586
                        query->FieldByName( "TESTSCENARIO_NO" )
3587
                           ->AsInteger ) );
3588
               }
3589
               else
3590
               {
3591
                  variable = &variables.defineVariable(
3592
                     fieldName.c_str() + 1 );
3593
               }
3594
               variable->setExpression( value.c_str() );
3595
               break;
3596
            default:
3597
               break;
3598
            }
3599
         }
3600
         query->Next();
3601
      }
3602
   }
3603
   __finally
3604
   {
3605
      delete query;
3606
      query = 0;
3607
   }
3608
}
3609
//---------------------------------------------------------------------------
3610
 
3611
void __fastcall TMainForm::readSequences( SequenceCollection & sequences, const std::string & project, const int & iteration )
3612
{
3613
   TADOQuery * query = 0;
3614
   try
3615
   {
3616
      query = new TADOQuery( this );
3617
      query->Connection = Data_Module->IntegrationDBConnection;
3618
 
3619
      AnsiString sqlStatement;
3620
      sqlStatement.sprintf(
3621
         "SELECT "
3622
            "SEQNAME,"
3623
            "SEQVALUE "
3624
         "FROM "
3625
            "SEQGEN "
3626
         "WHERE "
3627
            "PROJECT_CODE=\'%s\' AND "
3628
            "ITERATION=%d",
3629
         Utilities::EscapeString( project ).c_str(),
3630
         iteration );
3631
      query->SQL->Text = sqlStatement;
3632
      query->Open();
3633
 
3634
      std::string sequenceName;
3635
      int         value;
3636
      Sequence *  sequence;
3637
      while ( !query->Eof )
3638
      {
3639
         sequenceName   = query->FieldByName( "SEQNAME" )->AsString.c_str();
3640
         value       = query->FieldByName( "SEQVALUE" )->AsInteger;
3641
 
3642
         sequence = &sequences.getSequence( sequenceName, true, 0 );
3643
         sequence->setValue( value );
3644
         sequence->setUpdate( true );
3645
         sequence->setDirty( false );
3646
 
3647
         query->Next();
3648
      }
3649
   }
3650
   __finally
3651
   {
3652
      delete query;
3653
      query = 0;
3654
   }
3655
}
3656
//---------------------------------------------------------------------------
3657
 
3658
void __fastcall TMainForm::writeSequences( const SequenceCollection & sequences, const std::string & project, const int & iteration )
3659
{
3660
   TADOQuery * query = 0;
3661
   try
3662
   {
3663
      query = new TADOQuery( this );
3664
      query->Connection = Data_Module->IntegrationDBConnection;
3665
 
3666
      for ( std::map< std::string, Sequence * >::const_iterator
3667
            sequence = sequences.getCollection().begin();
3668
            sequence != sequences.getCollection().end();
3669
            ++sequence )
3670
      {
3671
         std::stringstream stream;
3672
         if ( sequence->second->isPersisted() && sequence->second->isDirty() )
3673
         {
3674
            if ( sequence->second->isUpdate() )
3675
            {
3676
               stream
3677
                  << "UPDATE SEQGEN SET "
3678
                     << "SEQVALUE=" << sequence->second->getValue()
3679
                  << " WHERE "
3680
                     << "PROJECT_CODE=\'" << Utilities::EscapeString( project ) << "\' AND "
3681
                     << "ITERATION=" << iteration << " AND "
3682
                     << "SEQNAME=\'" << Utilities::EscapeString( sequence->second->getName() ) << '\'';
3683
            }
3684
            else
3685
            {
3686
               stream
3687
                  << "INSERT INTO SEQGEN ( "
3688
                     "PROJECT_CODE,"
3689
                     "ITERATION,"
3690
                     "SEQNAME,"
3691
                     "SEQVALUE "
3692
                  " ) VALUES ( "
3693
                     << '\'' << Utilities::EscapeString( project ) << "\',"
3694
                     << iteration << ",\'"
3695
                     << Utilities::EscapeString( sequence->second->getName() ) << "\',"
3696
                     << sequence->second->getValue()
3697
                  << " )";
3698
            }
3699
 
3700
            query->SQL->Text = stream.str().c_str();
3701
            if ( query->ExecSQL() != 1 )
3702
            {
3703
               MTHROW( std::runtime_error, \
3704
                  "Cannot " \
3705
                  << ( sequence->second->isUpdate() ? "update" : "insert" ) \
3706
                  << " sequence \"" \
3707
                  << sequence->second->getName() \
3708
                  << "\"." );
3709
            }
3710
         }
3711
      }
3712
      SequenceGeneratorQuery->Refresh();     
3713
   }
3714
   __finally
3715
   {
3716
      delete query;
3717
      query = 0;
3718
   }
3719
}
3720
//---------------------------------------------------------------------------
3721
 
3722
void __fastcall TMainForm::GenerateTestTestCaseBtnClick(TObject *Sender)
3723
{
3724
   std::vector< int > scenarios;
3725
 
3726
   generateTransaction( scenarios );
3727
}
3728
//---------------------------------------------------------------------------
3729
 
3730
const unsigned __fastcall TMainForm::countTransactionsInIteration( const char * project, const int & iteration )
3731
{
3732
   unsigned count = 0;
3733
 
3734
   TADOQuery * query = 0;
3735
   try
3736
   {
3737
      query = new TADOQuery( this );
3738
      query->Connection = Data_Module->IntegrationDBConnection;
3739
 
3740
      AnsiString sqlStatement;
3741
      sqlStatement.sprintf(
3742
         "SELECT "
3743
            "COUNT(*) AS COUNT "
3744
         "FROM "
3745
            "TRANSACTION_SPECIFICATION "
3746
         "WHERE "
3747
            "PROJECT_CODE=\'%s\' AND "
3748
            "ITERATION=%d",
3749
         project,
3750
         iteration );
3751
      query->SQL->Text = sqlStatement;
3752
      query->Open();
3753
 
3754
      count = ( !query->Eof ? query->FieldByName( "COUNT" )->AsInteger : 0 );
3755
   }
3756
   __finally
3757
   {
3758
      delete query;
3759
      query = 0;
3760
   }
3761
 
3762
   return ( count );
3763
}
3764
//---------------------------------------------------------------------------
3765
 
3766
const unsigned __fastcall TMainForm::countTransactionsInScenario( const int & scenario )
3767
{
3768
   unsigned count = 0;
3769
 
3770
   TADOQuery * query = 0;
3771
   try
3772
   {
3773
      query = new TADOQuery( this );
3774
      query->Connection = Data_Module->IntegrationDBConnection;
3775
 
3776
      AnsiString sqlStatement;
3777
      sqlStatement.sprintf(
3778
         "SELECT "
3779
            "COUNT(*) AS COUNT "
3780
         "FROM "
3781
            "TRANSACTION_SPECIFICATION "
3782
         "WHERE "
3783
            "TESTSCENARIO_NO=%d",
3784
         scenario );
3785
      query->SQL->Text = sqlStatement;
3786
      query->Open();
3787
 
3788
      count = ( !query->Eof ? query->FieldByName( "COUNT" )->AsInteger : 0 );
3789
   }
3790
   __finally
3791
   {
3792
      delete query;
3793
      query = 0;
3794
   }
3795
 
3796
   return ( count );
3797
}
3798
//---------------------------------------------------------------------------
3799
 
3800
void __fastcall TMainForm::applyTemplatesToNewTransaction(
3801
                                const int &                 transaction,
3802
                        const TestScenarioTemplate *  all )
3803
{
3804
   TADOQuery * query = 0;
3805
   AnsiString sqlStatement;
3806
    try
3807
   {
3808
      query = new TADOQuery( this );
3809
      query->Connection = Data_Module->IntegrationDBConnection;
3810
 
3811
 
3812
      sqlStatement.sprintf(
3813
         "SELECT "
3814
            "XPATH,"
3815
            "FIELDVALUE, "
3816
            "DISPLAYABLE "
3817
         "FROM "
3818
            "TXNSPEC_VALUES "
3819
         "WHERE "
3820
            "TXNSPEC_NO=%d ",
3821
         transaction );
3822
      query->SQL->Text = sqlStatement;
3823
      query->Open();    
3824
        std::string  xpath;
3825
      std::string value;
3826
      unsigned matchCount = 0;
3827
 
3828
      AnsiString fieldValue;
3829
      while ( !query->Eof )
3830
      {
3831
         xpath = query->FieldByName( "XPATH" )->AsString.c_str();
3832
         fieldValue = query->FieldByName( "FIELDVALUE" )->AsString;
3833
 
3834
         matchCount = ( all ? all->findMatch( value, xpath ) : 0 );
3835
         if ( matchCount == 1 )
3836
         {
3837
            query->Edit();
3838
            query->FieldByName( "FIELDVALUE" )->AsString = value.c_str();
3839
             query->FieldByName( "DISPLAYABLE" )->AsString = "Y";
3840
            query->Post();
3841
         }
3842
         else if ( matchCount > 1 )
3843
         {
3844
            MTHROW( std::runtime_error, \
3845
               "Ambigious transaction template.  " \
3846
               << matchCount \
3847
               << " matches found for \"" \
3848
               << xpath \
3849
               << "\"." );
3850
         }
3851
 
3852
         query->Next();
3853
      }
3854
   }
3855
   __finally
3856
   {
3857
      delete query;
3858
      query = 0;
3859
   }
3860
 
3861
   try
3862
   {    
3863
        // hack to remove payment methods and payment values parents as they cause a generation problem.
3864
        query = new TADOQuery( this );
3865
      query->Connection = Data_Module->IntegrationDBConnection;
3866
        sqlStatement.sprintf(
3867
        "DELETE FROM "
3868
            "TXNSPEC_VALUES "
3869
        "WHERE "
3870
            "TXNSPEC_NO=%d "
3871
        "AND "
3872
            "DISPLAY_FIELDNAME IN (\'paymentMethod\',\'paymentValue\') ",
3873
        transaction );
3874
        query->SQL->Text = sqlStatement;
3875
        query->ExecSQL();
3876
   }
3877
   __finally
3878
   {
3879
       delete query;
3880
       query = 0;
3881
   }
3882
 
3883
}
3884
//---------------------------------------------------------------------------
3885
 
3886
void __fastcall TMainForm::applyTemplatesToTransaction(
3887
                        ProgressBar &              progressBar,
3888
                        const int &                transaction,
3889
                        const TestScenarioTemplate *  testScenario,
3890
                        const TestScenarioTemplate *  all )
3891
{
3892
   TADOQuery * query = 0;
3893
   try
3894
   {
3895
      query = new TADOQuery( this );
3896
      query->Connection = Data_Module->IntegrationDBConnection;
3897
 
3898
      AnsiString sqlStatement;
3899
      sqlStatement.sprintf(
3900
         "SELECT "
3901
            "XPATH,"
3902
            "FIELDVALUE, "
3903
            "DISPLAYABLE "
3904
         "FROM "
3905
            "TXNSPEC_VALUES "
3906
         "WHERE "
3907
            "TXNSPEC_NO=%d AND "
3908
            "USER_SUPPLIED=\'N\' AND "
3909
            "CHILD_COUNT=0",
3910
         transaction );
3911
      query->SQL->Text = sqlStatement;
3912
      query->Open();
3913
 
3914
      std::string xpath;
3915
      std::string value;
3916
      unsigned matchCount = 0;
3917
 
3918
      AnsiString fieldValue;
3919
      while ( !query->Eof )
3920
      {
3921
         xpath = query->FieldByName( "XPATH" )->AsString.c_str();
3922
         fieldValue = query->FieldByName( "FIELDVALUE" )->AsString;
3923
         matchCount = ( testScenario ? testScenario->findMatch( value, xpath ) : 0 );
3924
 
3925
         if ( matchCount == 1 )
3926
         {
3927
            query->Edit();
3928
            query->FieldByName( "FIELDVALUE" )->AsString = value.c_str();
3929
            query->FieldByName( "DISPLAYABLE" )->AsString = "Y";
3930
            query->Post();
3931
         }
3932
         else if ( matchCount > 1 )
3933
         {
3934
            MTHROW( std::runtime_error, \
3935
               "Ambigious scenario transaction template.  " \
3936
               << matchCount \
3937
               << " matches found for \"" \
3938
               << xpath \
3939
               << "\"." );
3940
         }
3941
         else
3942
         {
3943
            matchCount = ( all ? all->findMatch( value, xpath ) : 0 );
3944
            if ( matchCount == 1 )
3945
            {
3946
               query->Edit();
3947
               query->FieldByName( "FIELDVALUE" )->AsString = value.c_str();
3948
                query->FieldByName( "DISPLAYABLE" )->AsString = "Y";
3949
               query->Post();
3950
            }
3951
            else if ( matchCount > 1 )
3952
            {
3953
               MTHROW( std::runtime_error, \
3954
                  "Ambigious transaction template.  " \
3955
                  << matchCount \
3956
                  << " matches found for \"" \
3957
                  << xpath \
3958
                  << "\"." );
3959
            }
3960
         }
3961
 
3962
         query->Next();
3963
      }
3964
   }
3965
   __finally
3966
   {
3967
      delete query;
3968
      query = 0;
3969
   }
3970
}
3971
 
3972
//---------------------------------------------------------------------------
3973
 
3974
void __fastcall TMainForm::applyTemplatesToScenario( ProgressBar & progressBar, const int & scenario )
3975
{
3976
   /**
3977
    * Iterate through the collection of transactions defined for this scenario
3978
    * and for each field attempt to apply every field template defined.  When
3979
    * multiple fields match, raise an exception and roll any template
3980
    * applications back.
3981
    */
3982
   TestScenarioTemplate *  testScenario   = m_transactionTemplates.findTestScenarioTemplate( scenario );
3983
   TestScenarioTemplate *  all            = m_transactionTemplates.findTestScenarioTemplate( 0 );
3984
 
3985
   if ( testScenario || all )
3986
   {
3987
      TADOQuery * query = 0;
3988
      try
3989
      {
3990
         query = new TADOQuery( this );
3991
         query->Connection = Data_Module->IntegrationDBConnection;
3992
 
3993
         AnsiString sqlStatement;
3994
         sqlStatement.sprintf(
3995
            "SELECT "
3996
               "TXNSPEC_NO,"
3997
               "NAME "
3998
            "FROM "
3999
               "TRANSACTION_SPECIFICATION,"
4000
               "MASS_TXNS "
4001
            "WHERE "
4002
               "TESTSCENARIO_NO=%d AND "
4003
               "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND "
4004
               "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND "
4005
               "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND "
4006
               "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE "
4007
            "ORDER BY "
4008
               "TESTSCENARIO_NO,"
4009
               "TXNSPEC_NO",
4010
            scenario );
4011
         query->SQL->Text = sqlStatement;
4012
         query->Open();
4013
 
4014
         AnsiString message;
4015
         while ( !query->Eof )
4016
         {
4017
            message.sprintf(
4018
               " Applying template to %s ...",
4019
               query->FieldByName( "NAME" )->AsString.c_str() );
4020
            MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
4021
            Application->ProcessMessages();
4022
 
4023
            applyTemplatesToTransaction(
4024
               progressBar,
4025
               query->FieldByName( "TXNSPEC_NO" )->AsInteger,
4026
               testScenario,
4027
               all );
4028
            progressBar.increment();
4029
            query->Next();
4030
         }
4031
      }
4032
      __finally
4033
      {
4034
         delete query;
4035
         query = 0;
4036
 
4037
         MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "";
4038
      }
4039
   }
4040
}
4041
//---------------------------------------------------------------------------
4042
 
4043
void __fastcall TMainForm::ApplyTemplatesToScenarioClick(TObject *Sender)
4044
{
4045
   // The scenario, our context, is kept in the tag of our parent menu.
4046
   TPopupMenu * menu
4047
      = dynamic_cast< TPopupMenu * >(
4048
         dynamic_cast< TMenuItem * >( Sender )->GetParentMenu() );
4049
   if ( menu )
4050
   {
4051
      const int scenario = menu->Tag;
4052
      try
4053
      {
4054
         const TCursor Save_Cursor = Screen->Cursor;
4055
         try
4056
         {
4057
            Screen->Cursor = crHourGlass;
4058
 
4059
            const unsigned count = countTransactionsInScenario( scenario );
4060
            m_progressBar->open( count * 2 );
4061
            buildTransactionsForScenario(
4062
               m_transactionCache,
4063
               *m_progressBar,
4064
               scenario,
4065
               m_schema_handle,
4066
               m_currentiteration );
4067
 
4068
            try
4069
            {
4070
               Data_Module->IntegrationDBConnection->BeginTrans();
4071
               applyTemplatesToScenario( *m_progressBar, scenario );
4072
               Data_Module->IntegrationDBConnection->CommitTrans();
4073
            }
4074
            catch ( ... )
4075
            {
4076
               Data_Module->IntegrationDBConnection->RollbackTrans();
4077
               throw;
4078
            }
4079
            m_progressBar->update( count );
4080
         }
4081
         __finally
4082
         {
4083
            m_progressBar->close();
4084
            Screen->Cursor = Save_Cursor;
4085
         }
4086
      }
4087
      catch ( const std::exception & exception )
4088
      {
4089
         MessageDlg(
4090
            exception.what(),
4091
            mtError, TMsgDlgButtons() << mbOK, 0 );
4092
      }
4093
      catch ( ... )
4094
      {
4095
         MessageDlg(
4096
            "Unknown exception applying templates to this scenario.",
4097
            mtError, TMsgDlgButtons() << mbOK, 0 );
4098
      }
4099
   }
4100
}
4101
 
4102
 
4103
 
4104
string __fastcall TMainForm::FindField(const string &structure_handle, int fieldtag)
4105
{
4106
   string                  field_path;
4107
   vector<string>          structure_attributes;
4108
   vector<string>::iterator   s_itr;
4109
 
4110
   XMLSchema->GetAttributes(structure_handle, structure_attributes);
4111
 
4112
    s_itr = structure_attributes.begin();
4113
    while (s_itr != structure_attributes.end())
4114
    {
4115
        string   elementtype;
4116
        string datatype;
4117
 
4118
        XMLSchema->GetAttributeProperty((*s_itr), "type", elementtype);
4119
 
4120
        if (elementtype == "field")
4121
        {
4122
            XMLSchema->GetAttributeProperty((*s_itr), "datatype", datatype);
4123
 
4124
            if (datatype == "Struct")
4125
            {
4126
               field_path = FindField((*s_itr), fieldtag);
4127
 
4128
                if (!field_path.empty())
4129
                {
4130
                  break;
4131
                }
4132
            }
4133
            else
4134
            {
4135
                string  xml_fieldtag;
4136
                XMLSchema->GetAttributeProperty((*s_itr), "tag", xml_fieldtag);
4137
 
4138
                if ( fieldtag == atoi(xml_fieldtag.c_str()) )
4139
                {
4140
                    field_path = (*s_itr);
4141
                    break;
4142
                }
4143
            }
4144
        }
4145
        else
4146
        if (elementtype == "repeat")
4147
        {
4148
            string   repeatname;
4149
            XMLSchema->GetAttributeProperty((*s_itr), "name", repeatname);
4150
 
4151
            string      repeatAttribute = (*s_itr)+".1";
4152
 
4153
            field_path = FindField(repeatAttribute, fieldtag);
4154
 
4155
            if (!field_path.empty())
4156
            {
4157
                break;
4158
            }
4159
        }
4160
 
4161
        s_itr++;
4162
    }
4163
 
4164
    return field_path;
4165
}
4166
//---------------------------------------------------------------------------
4167
 
4168
void __fastcall TMainForm::FieldEnumValuesDblClick(TObject *Sender)
4169
{
4170
   TADOQuery * query = 0;
4171
 
4172
   if ( TransactionStructurePageControl->ActivePage == PayloadStructureTabSheet )
4173
   {
4174
      query = TxnValuesQuery;
4175
   }
4176
   else if ( TransactionStructurePageControl->ActivePage == HeaderStructureTabSheet )
4177
   {
4178
      query = TxnHeaderValuesQuery;
4179
   }
4180
 
4181
 
4182
   if ( query )
4183
   {
4184
      if ( query->State != dsEdit )
4185
      {
4186
         query->Edit();
4187
      }
4188
 
4189
      query->FieldByName( "FIELDVALUE" )->AsString = FieldEnumValues->Items->Strings[ FieldEnumValues->ItemIndex ];
4190
   }
4191
}
4192
//---------------------------------------------------------------------------
4193
 
4194
 
4195
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
4196
{
4197
   XMLSchema->Active = false;
4198
 
4199
   if( m_Registry != 0 ) m_Registry->CloseKey();
4200
}
4201
//---------------------------------------------------------------------------
4202
 
4203
void __fastcall TMainForm::SetGenerationDirectoryClick(TObject *Sender)
4204
{
4205
   AnsiString  directory;
4206
 
4207
   if ( SelectDirectory("Select Generation Directory", "c:\\", directory) )
4208
    {
4209
        if (m_Registry != NULL)
4210
        {
4211
            m_Registry->WriteString("MRUGenerationDir", directory);
4212
        }
4213
   }
4214
}
4215
//---------------------------------------------------------------------------
4216
 
4217
void __fastcall TMainForm::TestCaseGridRowChanging(TObject *Sender,
4218
     int OldRow, int NewRow, bool &Allow)
4219
{
4220
   TCursor Save_Cursor = Screen->Cursor;
4221
   Screen->Cursor = crHourGlass;    // Show hourglass cursor
4222
 
4223
   try
4224
   {
4225
 
4226
      TxnStepsQuery->Close(); 
4227
      //TestCasesTabSheet->TabVisible = true;
4228
        //MainPageControl->ActivePage = TestCasesTabSheet;
4229
     // TestScenariosTabSheet->TabVisible = false;
4230
 
4231
      if ( (m_currentproject.Length() > 0) && (m_currentiteration != 0) )
4232
      {
4233
         TestCaseTreeView->Items->BeginUpdate();
4234
 
4235
         TestCaseTreeView->Items->Clear();
4236
 
4237
 
4238
         TADOQuery   *query = new TADOQuery(this);
4239
         query->Connection = Data_Module->IntegrationDBConnection;
4240
 
4241
         m_currenttestcaseid = TestCaseQuery->FieldByName("TESTCASE_ID")->AsString;            
4242
         m_currentcaserepeat = TestCaseQuery->FieldByName("CASE_REPEAT")->AsInteger;
4243
         m_currentcasedelay = TestCaseQuery->FieldByName("REPEAT_DELAY")->AsInteger;
4244
 
4245
         AnsiString  sql_statement;          
4246
         sql_statement.sprintf("SELECT * FROM TEST_SCENARIOS "
4247
                               "WHERE PROJECT_CODE='%s' AND ITERATION=%d "
4248
                               "AND   TESTCASE_ID='%s' "
4249
                               "ORDER BY TESTCASE_SEQNO",
4250
                               m_currentproject.c_str(),
4251
                               m_currentiteration,
4252
                               m_currenttestcaseid.c_str());
4253
 
4254
         query->SQL->Text = sql_statement;
4255
         query->Open();
4256
 
4257
         int count = 0;
4258
         while (!query->Eof)
4259
         {
4260
            AnsiString  testcase_desc;
4261
 
4262
            testcase_desc.sprintf("(%d) %s",
4263
                             query->FieldByName("TESTCASE_SEQNO")->AsInteger,
4264
                             query->FieldByName("NAME")->AsString.c_str()
4265
                             );
4266
 
4267
            int   testscenario_no = query->FieldByName("TESTSCENARIO_NO")->AsInteger;
4268
 
4269
            TTreeNode *testcase_node = TestCaseTreeView->Items->AddObject(NULL, testcase_desc, (void *)testscenario_no);
4270
            LoadTestCaseNodes(testcase_node);
4271
 
4272
            ++count;
4273
            query->Next();
4274
         }
4275
 
4276
         GenerateTestTestCaseBtn->Caption = "Generate Test Case: " + m_currenttestcaseid;
4277
         GenerateTestTestCaseBtn->Enabled = ( count > 0 );
4278
 
4279
         delete query;
4280
 
4281
         TestCaseTreeView->Items->EndUpdate();
4282
         TestCaseTreeView->FullExpand();
4283
 
4284
         /* also refresh the Test Steps tab */
4285
 //        if (TxnStepsQuery->State == dsEdit) TxnStepsQuery->Post();         
4286
         // TxnStepsQuery->Close();                 
4287
         TxnStepsQuery->SQL->Text = sql_statement;
4288
         TxnStepsQuery->Open();
4289
 //        TxnStepsQuery->Edit();
4290
 
4291
        }
4292
    }
4293
   __finally
4294
    {
4295
       Screen->Cursor = Save_Cursor;
4296
    }
4297
 
4298
    Allow = true;
4299
}
4300
//---------------------------------------------------------------------------
4301
 
4302
void __fastcall TMainForm::TestCaseQueryAfterClose(TDataSet *DataSet)
4303
{
4304
   TestScenarioToolBar->Enabled = false;
4305
    AddTestCaseNode->Enabled = false;
4306
// InitTxnBtn->Enabled = false;
4307
// GenerateAllTxnsBtn->Enabled = false;
4308
}
4309
//---------------------------------------------------------------------------
4310
 
4311
void __fastcall TMainForm::TestCaseQueryAfterOpen(TDataSet *DataSet)
4312
{
4313
   TestScenarioToolBar->Enabled = true;
4314
 
4315
   AddTestCaseNode->Enabled = true;
4316
// InitTxnBtn->Enabled = true;
4317
// GenerateAllTxnsBtn->Enabled = true;
4318
}
4319
//---------------------------------------------------------------------------
4320
 
4321
void __fastcall TMainForm::SequenceGeneratorQueryAfterInsert(
4322
      TDataSet *DataSet)
4323
{
4324
    DataSet->FieldByName("PROJECT_CODE")->AsString = m_currentproject;
4325
    DataSet->FieldByName("ITERATION")->AsInteger = m_currentiteration;
4326
}
4327
//---------------------------------------------------------------------------
4328
 
4329
void __fastcall TMainForm::TestCaseQueryBeforePost(TDataSet *DataSet)
4330
{
4331
   //DataSet->FieldByName("USECASE_ID")->AsString = DataSet->FieldByName("TESTCASE_ID")->AsString;
4332
   if( DataSet->FieldByName("CASE_REPEAT")->AsInteger < 1) DataSet->FieldByName("CASE_REPEAT")->AsInteger = 1;
4333
   if( DataSet->FieldByName("REPEAT_DELAY")->AsInteger > 360) DataSet->FieldByName("REPEAT_DELAY")->AsInteger = 360;
4334
   if( DataSet->FieldByName("BATCH_SIZE")->AsInteger < 1) DataSet->FieldByName("BATCH_SIZE")->AsInteger = 1;
4335
}
4336
//---------------------------------------------------------------------------
4337
 
4338
 
4339
void __fastcall TMainForm::TxnStepsQueryBeforeClose(TDataSet *DataSet)
4340
{
4341
    if (DataSet->State == dsEdit )
4342
   {
4343
       //DataSet->FieldByName("TESTCASE_ID")->AsString = m_currenttestcaseid;
4344
       //DataSet->FieldByName("USECASE")->AsString = m_currenttestcaseid;
4345
       //DataSet->FieldByName("PROJECT_CODE")->AsString = m_currentproject;
4346
       //DataSet->FieldByName("ITERATION")->AsInteger = m_currentiteration;
4347
       if( DataSet->FieldByName("REPEAT_COUNT")->AsInteger < 1) DataSet->FieldByName("REPEAT_COUNT")->AsInteger = 1;
4348
       DataSet->Post();
4349
   }
4350
}
4351
//---------------------------------------------------------------------------
4352
 
4353
void __fastcall TMainForm::TestCaseTreeViewEditing(TObject *Sender,
4354
      TTreeNode *Node, bool &AllowEdit)
4355
{
4356
    if (Node->Level == 0)
4357
    {
4358
      AllowEdit = true;
4359
    }
4360
    else
4361
    {
4362
        AllowEdit = false;
4363
    }
4364
}
4365
//---------------------------------------------------------------------------
4366
 
4367
void __fastcall TMainForm::TestCaseTreeViewEdited(TObject *Sender,
4368
     TTreeNode *Node, AnsiString &S)
4369
{
4370
   // We've enable editing of the root level only, but we'll check anyway.
4371
   if (Node->Level == 0)
4372
   {
4373
      const int   testscenario_no = (int)(Node->Data);
4374
      TADOQuery * query           = 0;
4375
 
4376
      try
4377
        {
4378
            query = new TADOQuery( this );
4379
         query->Connection = Data_Module->IntegrationDBConnection;
4380
 
4381
            AnsiString  sql_statement;
4382
            AnsiString  name;
4383
            sql_statement.sprintf(
4384
                "UPDATE TEST_SCENARIOS SET NAME='%s' WHERE TESTSCENARIO_NO=%d",
4385
            Utilities::EscapeString( getNameFromNode( name, S ) ).c_str(),
4386
                testscenario_no );
4387
            query->SQL->Text = sql_statement;
4388
 
4389
            Data_Module->IntegrationDBConnection->BeginTrans();
4390
            try
4391
            {
4392
                query->ExecSQL();
4393
                Data_Module->IntegrationDBConnection->CommitTrans();
4394
            }
4395
            catch ( ... )
4396
            {
4397
                Data_Module->IntegrationDBConnection->RollbackTrans();
4398
            }
4399
        }
4400
        __finally
4401
        {
4402
            delete query;
4403
        }
4404
    }
4405
}
4406
//---------------------------------------------------------------------------
4407
 
4408
void __fastcall TMainForm::TestScenarioPropertiesClick(TObject *Sender)
4409
{
4410
   TestScenarioPropertiesForm->ShowForm( m_testscenario_no );
4411
}
4412
//---------------------------------------------------------------------------
4413
 
4414
void __fastcall TMainForm::TestCaseTreeViewContextPopup(TObject *Sender,
4415
     TPoint &MousePos, bool &Handled)
4416
{
4417
   TTreeView * view = dynamic_cast< TTreeView * >( Sender );
4418
   if ( view )
4419
   {
4420
      TTreeNode *    Node  = view->GetNodeAt( MousePos.x, MousePos.y );
4421
      const TPoint   screen   = TestCaseTreeView->ClientToScreen( MousePos );
4422
 
4423
      if ( Node )
4424
      {
4425
         switch ( Node->Level )
4426
         {
4427
         case 0:
4428
            // Rebuild the transaction templates, they may have changed.
4429
            buildTransactionTemplates(
4430
               m_transactionTemplates,
4431
               m_currentproject,
4432
               m_currentiteration );
4433
 
4434
            ApplyTemplatesToScenario->Enabled = (
4435
               m_transactionTemplates.haveTemplatesForScenario(
4436
                  reinterpret_cast< int >( Node->Data ) ) );
4437
 
4438
            ScenarioPopupMenu->Tag = reinterpret_cast< int >( Node->Data );
4439
            ScenarioPopupMenu->Popup( screen.x, screen.y );
4440
            break;
4441
         case 1:
4442
            TransactionPopupMenu->Popup( screen.x, screen.y );
4443
            break;
4444
         }
4445
      }
4446
   }
4447
}
4448
//---------------------------------------------------------------------------
4449
 
4450
 
4451
void __fastcall TMainForm::DeleteScenarioChildren(int testscenario_no)
4452
{
4453
   bool refresh_testcases = false;
4454
   TADOQuery   *query = new TADOQuery(this);
4455
   AnsiString  sql_statement;
4456
   query->Connection = Data_Module->IntegrationDBConnection;
4457
 
4458
   try
4459
   {
4460
      Data_Module->IntegrationDBConnection->BeginTrans();
4461
 
4462
      sql_statement.sprintf(
4463
         "DELETE FROM TXNSPEC_VALUES WHERE TESTSCENARIO_NO=%d",
4464
         testscenario_no );
4465
 
4466
      query->SQL->Text = sql_statement;
4467
      query->ExecSQL();
4468
 
4469
      sql_statement="";
4470
      sql_statement.sprintf(
4471
         "DELETE FROM TRANSACTION_SPECIFICATION WHERE TESTSCENARIO_NO=%d",
4472
         testscenario_no );
4473
 
4474
      query->SQL->Text = sql_statement;
4475
      query->ExecSQL();
4476
 
4477
      sql_statement="";
4478
      sql_statement.sprintf(
4479
         "DELETE FROM ITERATION_PARAMS WHERE TESTSCENARIO_NO=%d",
4480
         testscenario_no );
4481
 
4482
      query->SQL->Text = sql_statement;
4483
      query->ExecSQL();
4484
 
4485
      //sql_statement="";
4486
      //sql_statement.sprintf(
4487
      // "DELETE FROM TEST_SCENARIOS WHERE TESTSCENARIO_NO=%d",
4488
      // testscenario_no );
4489
 
4490
      //query->SQL->Text = sql_statement;
4491
      //query->ExecSQL();
4492
 
4493
      Data_Module->IntegrationDBConnection->CommitTrans();
4494
 
4495
      //refresh_testcases = true;
4496
 
4497
      //ResequenceTestCases(current_node);
4498
   }
4499
   catch(...)
4500
   {
4501
      Data_Module->IntegrationDBConnection->RollbackTrans();
4502
   }
4503
 
4504
   delete query;
4505
 
4506
/*
4507
   if (refresh_testcases)
4508
   {
4509
      bool allow;
4510
      TestCaseGridRowChanging(Sender, 0, 1, allow = true);
4511
   }
4512
*/
4513
    }
4514
//---------------------------------------------------------------------------
4515
 
4516
 
4517
void __fastcall TMainForm::DeleteScenarioClick(TObject *Sender)
4518
{
4519
   bool refresh_testcases = false;
4520
 
4521
   for ( unsigned selected_item=0;
4522
        selected_item<TestCaseTreeView->SelectionCount;
4523
        selected_item++ )
4524
   {
4525
      TTreeNode * current_node = TestCaseTreeView->Selections[ selected_item ];
4526
      if ( current_node != NULL )
4527
      {
4528
         if (current_node->Level == 0) // Remove Test Scenario
4529
         {
4530
            // Confirm deletion
4531
            AnsiString  message;
4532
            message.sprintf( "Are you sure you want to delete test scenario '%s'?", current_node->Text );
4533
 
4534
            if ( MessageDlg( message, mtConfirmation, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrYes )
4535
            {
4536
               int   testscenario_no = (int)(current_node->Data);
4537
 
4538
               TADOQuery   *query = new TADOQuery(this);
4539
               AnsiString  sql_statement;
4540
               query->Connection = Data_Module->IntegrationDBConnection;
4541
 
4542
               try
4543
               {
4544
                  Data_Module->IntegrationDBConnection->BeginTrans();
4545
 
4546
                  sql_statement.sprintf(
4547
                     "DELETE FROM TXNSPEC_VALUES WHERE TESTSCENARIO_NO=%d",
4548
                     testscenario_no );
4549
 
4550
                  query->SQL->Text = sql_statement;
4551
                  query->ExecSQL();
4552
 
4553
                  sql_statement="";
4554
                  sql_statement.sprintf(
4555
                     "DELETE FROM TRANSACTION_SPECIFICATION WHERE TESTSCENARIO_NO=%d",
4556
                     testscenario_no );
4557
 
4558
                  query->SQL->Text = sql_statement;
4559
                  query->ExecSQL();
4560
 
4561
                  sql_statement="";
4562
                  sql_statement.sprintf(
4563
                     "DELETE FROM ITERATION_PARAMS WHERE TESTSCENARIO_NO=%d",
4564
                     testscenario_no );
4565
 
4566
                  query->SQL->Text = sql_statement;
4567
                  query->ExecSQL();
4568
 
4569
                  sql_statement="";
4570
                  sql_statement.sprintf(
4571
                     "DELETE FROM TEST_SCENARIOS WHERE TESTSCENARIO_NO=%d",
4572
                     testscenario_no );
4573
 
4574
                  query->SQL->Text = sql_statement;
4575
                  query->ExecSQL();
4576
 
4577
                  Data_Module->IntegrationDBConnection->CommitTrans();
4578
 
4579
                  refresh_testcases = true;
4580
 
4581
                  ResequenceTestCases(current_node);
4582
               }
4583
               catch(...)
4584
               {
4585
                  Data_Module->IntegrationDBConnection->RollbackTrans();
4586
               }
4587
 
4588
               delete query;
4589
            }
4590
         }
4591
      }
4592
   }
4593
 
4594
   if (refresh_testcases)
4595
   {
4596
      bool allow;
4597
      TestCaseGridRowChanging(Sender, 0, 1, allow = true);
4598
   }
4599
}
4600
 
4601
//---------------------------------------------------------------------------
4602
 
4603
void __fastcall TMainForm::TransactionValueGrid1BeforeContractNode(
4604
     TObject *Sender, int ARow, int ARowReal, bool &Allow)
4605
{
4606
   Allow = ( TransactionValueGrid->RealRow <= ARowReal );
4607
}
4608
//---------------------------------------------------------------------------
4609
 
4610
const bool __fastcall TMainForm::isParent( const int & ordinal )
4611
{
4612
   return ( std::find(
4613
            m_parents.begin(),
4614
            m_parents.end(),
4615
            ordinal ) != m_parents.end() );
4616
}
4617
//---------------------------------------------------------------------------
4618
 
4619
void __fastcall TMainForm::TransactionValueGridCanEditCell(TObject *Sender,
4620
     int ARow, int ACol, bool &CanEdit)
4621
{
4622
#if INCLUDE_PARENTS
4623
   /**
4624
    *  Use the real row as the ordinal number into the dataset.  When the row
4625
    *  has children, it cannot be edited, otherwise it can.
4626
    */
4627
   CanEdit = !isParent( TransactionValueGrid->RealRowIndex( ARow ) );
4628
#endif
4629
}
4630
//---------------------------------------------------------------------------
4631
 
4632
void __fastcall TMainForm::TransactionValueGridGetDisplText(
4633
     TObject *Sender, int ACol, int ARow, AnsiString &Value)
4634
{
4635
#if INCLUDE_PARENTS
4636
   const int row = TransactionValueGrid->RealRowIndex( ARow );
4637
   if ( row > 0 )
4638
   {
4639
      switch ( TransactionValueGrid->RealColIndex( ACol ) )
4640
      {
4641
      case 2:  // The value column.
4642
         /**
4643
          * Use the real row as the ordinal number into the dataset.  When
4644
          * the row has children, it cannot be edited, otherwise it can.
4645
          */
4646
         if ( isParent( row ) )
4647
         {
4648
            Value = "{...}";
4649
         }
4650
         break;
4651
      case 3:  // The checkbox column.
4652
         if ( isParent( row ) )
4653
         {
4654
            Value = "";
4655
         }
4656
         break;
4657
      }
4658
   }
4659
#endif
4660
}
4661
//---------------------------------------------------------------------------
4662
 
4663
void __fastcall TMainForm::TransactionGridRowChanging( TADOQuery & query, const char * structureName )
4664
{
4665
   TxnFieldComments->Lines->Clear();
4666
   FieldEnumValues->Clear();
4667
   FieldDatatype->Clear();
4668
   DocDataType->Clear();
4669
   IncludedInMac->Checked = false;
4670
 
4671
   if ( query.State != dsInactive && query.RecordCount )
4672
   {
4673
      if (!m_schema_handle.empty())
4674
      {
4675
         const int   fieldtag = query.FieldByName("FIELDTAG")->AsInteger;
4676
         string      structure_handle;
4677
 
4678
         try
4679
         {
4680
            XMLSchema->Create(m_schema_handle.c_str(), structureName, m_currentiteration, structure_handle, NULL);
4681
 
4682
            string   field_path = FindField(structure_handle, fieldtag);
4683
 
4684
            if (!field_path.empty())
4685
            {
4686
               std::string fieldcomments;
4687
               std::string datatype;
4688
               std::string docdatatype;
4689
               std::string includedInMac;
4690
 
4691
               XMLSchema->GetAttributeProperty(field_path, "comments", fieldcomments);
4692
               TxnFieldComments->Lines->Add(fieldcomments.c_str());
4693
 
4694
               XMLSchema->GetAttributeProperty(field_path, "datatype", datatype);
4695
               FieldDatatype->Text = datatype.c_str();
4696
 
4697
               XMLSchema->GetAttributeProperty(field_path, "docdatatype", docdatatype );
4698
               DocDataType->Text = docdatatype.c_str();
4699
 
4700
               XMLSchema->GetAttributeProperty(field_path, "inMac", includedInMac );
4701
               IncludedInMac->Checked = ( includedInMac == "true" );
4702
 
4703
               string valuemap;
4704
 
4705
               XMLSchema->GetAttributeProperty(field_path, "valuemap", valuemap);
4706
 
4707
               if (!valuemap.empty())
4708
               {
4709
                  vector<string>          enum_values;
4710
                  if (XMLSchema->GetEnumerationValues(m_schema_handle, valuemap.c_str(), enum_values))
4711
                  {
4712
                     vector<string>::iterator   eitr = enum_values.begin();
4713
                     while (eitr != enum_values.end())
4714
                     {
4715
                        FieldEnumValues->AddItem( (*eitr).c_str(), NULL);
4716
 
4717
                        ++eitr;
4718
                     }
4719
                  }
4720
               }
4721
            }
4722
         }
4723
         __finally
4724
         {
4725
            XMLSchema->Destroy( structure_handle );
4726
         }
4727
      }
4728
   }
4729
}
4730
//---------------------------------------------------------------------------
4731
 
4732
void __fastcall TMainForm::TransactionValueGridRowChanging(TObject *Sender,
4733
     int OldRow, int NewRow, bool &Allow)
4734
{
4735
   TransactionGridRowChanging( *TxnValuesQuery, m_structure_name.c_str() );
4736
}
4737
 
4738
//---------------------------------------------------------------------------
4739
 
4740
void __fastcall TMainForm::HeaderStructureGridRowChanging(TObject *Sender,
4741
     int OldRow, int NewRow, bool &Allow)
4742
{
4743
   TransactionGridRowChanging( *TxnHeaderValuesQuery, g_headerStructure );
4744
}
4745
//---------------------------------------------------------------------------
4746
 
4747
void __fastcall TMainForm::HeaderStructureTabSheetShow(TObject *Sender)
4748
{
4749
   TransactionGridRowChanging( *TxnHeaderValuesQuery, g_headerStructure );
4750
}
4751
//---------------------------------------------------------------------------
4752
 
4753
void __fastcall TMainForm::PayloadStructureTabSheetShow(TObject *Sender)
4754
{
4755
   TransactionGridRowChanging( *TxnValuesQuery, m_structure_name.c_str() );
4756
}
4757
//---------------------------------------------------------------------------
4758
 
4759
void __fastcall TMainForm::MainStatusBarResize(TObject *Sender)
4760
{
4761
   if ( m_progressBar )
4762
   {
4763
      RECT Rect;
4764
      MainStatusBar->Perform( SB_GETRECT, 0, (LPARAM)&Rect );
4765
 
4766
      const int progressPanel = 1;
4767
      int offset = 0;
4768
      for ( int i = 0; i < progressPanel; i++ )
4769
      {
4770
         offset += MainStatusBar->Panels->Items[ i ]->Width;
4771
      }
4772
 
4773
      m_progressBar->resize(
4774
         Rect.top,
4775
         Rect.left + offset,
4776
         MainStatusBar->Panels->Items[ progressPanel ]->Width,
4777
         Rect.bottom - Rect.top );
4778
   }
4779
}
4780
//---------------------------------------------------------------------------
4781
 
4782
void __fastcall TMainForm::TransactionValueGridKeyDown(TObject *Sender,
4783
      WORD &Key, TShiftState Shift)
4784
{
4785
   if ( Key == 'F' )
4786
   {
4787
      TShiftState mask;
4788
      mask << ssCtrl;
4789
 
4790
      if ( Shift * mask == mask )
4791
      {
4792
         TransactionValueGridFindDialog->Execute();
4793
      }
4794
   }
4795
}
4796
//---------------------------------------------------------------------------
4797
 
4798
void __fastcall TMainForm::HeaderStructureGridKeyDown(TObject *Sender,
4799
      WORD &Key, TShiftState Shift)
4800
{
4801
   if ( Key == 'F' )
4802
   {
4803
      TShiftState mask;
4804
      mask << ssCtrl;
4805
 
4806
      if ( Shift * mask == mask )
4807
      {
4808
         HeaderStructureGridFindDialog->Execute();
4809
      }
4810
   }
4811
}
4812
 
4813
//---------------------------------------------------------------------------
4814
 
4815
void __fastcall TMainForm::ImportTransactionActionExecute(TObject *Sender)
4816
{
4817
   TTreeNode * currentNode = TestCaseTreeView->Selected;
4818
 
4819
   if ( currentNode )
4820
   {
4821
      // Are we importing a scenario, or a single transaction?
4822
      if ( currentNode->Level == 0 )
4823
      {
4824
         const int testScenarioNumber
4825
            = reinterpret_cast< int >( currentNode->Data );
4826
      }
4827
   }
4828
}
4829
//---------------------------------------------------------------------------
4830
 
4831
 
4832
 
4833
 
4834
 
4835
void __fastcall TMainForm::buildExecutionSchedule( TransactionSpecification & transactionSpecification )
4836
{
4837
   TADOQuery * query = 0;
4838
   try
4839
   {
4840
      query = new TADOQuery( this );
4841
      query->Connection = Data_Module->IntegrationDBConnection;
4842
 
4843
      AnsiString sqlStatement;
4844
      sqlStatement.sprintf(
4845
         "SELECT "
4846
            "XPATH,"
4847
            "FIELDVALUE "
4848
         "FROM "
4849
            "TXNSPEC_VALUES "
4850
         "WHERE "
4851
            "TXNSPEC_NO=%d AND "
4852
            "FIELDVALUE IS NOT NULL AND "
4853
            "OBSOLETE=\'N\' "
4854
         "ORDER BY "
4855
            "ORDINAL",
4856
         transactionSpecification.getTransactionSpecificationNumber() );
4857
      query->SQL->Text = sqlStatement;
4858
      query->Open();
4859
 
4860
      TransactionSpecificationValue * value = 0;
4861
      while ( !query->Eof )
4862
      {
4863
         value = &transactionSpecification.getTransactionField(
4864
            query->FieldByName( "XPATH" )->AsString.c_str() );
4865
 
4866
         value->setExpression( query->FieldByName( "FIELDVALUE" )->AsString.c_str() );
4867
 
4868
         query->Next();
4869
      }
4870
   }
4871
   __finally
4872
   {
4873
      delete query;
4874
      query = 0;
4875
   }
4876
}
4877
//---------------------------------------------------------------------------
4878
 
4879
void __fastcall TMainForm::buildExecutionSchedule( TestScenario & testScenario )
4880
{
4881
   TADOQuery * query = 0;
4882
   try
4883
   {
4884
      query = new TADOQuery( this );
4885
      query->Connection = Data_Module->IntegrationDBConnection;
4886
 
4887
      AnsiString sqlStatement;
4888
      sqlStatement.sprintf(
4889
         "SELECT "
4890
            "TRANSACTION_SPECIFICATION.TXNSPEC_NO AS TXNSPEC_NO,"
4891
            "TRANSACTION_SPECIFICATION.UDTYPE AS UDTYPE,"
4892
            "TRANSACTION_SPECIFICATION.UDSUBTYPE AS UDSUBTYPE,"
4893
            "MASS_TXNS.NAME AS NAME "
4894
         "FROM "
4895
            "TRANSACTION_SPECIFICATION,"
4896
            "MASS_TXNS "
4897
         "WHERE "
4898
            "TESTSCENARIO_NO=%d AND "
4899
            "TRANSACTION_SPECIFICATION.PROJECT_CODE = MASS_TXNS.PROJECTCODE AND "
4900
            "TRANSACTION_SPECIFICATION.ITERATION = MASS_TXNS.ITERATION AND "
4901
            "TRANSACTION_SPECIFICATION.UDTYPE = MASS_TXNS.UDTYPE AND "
4902
            "TRANSACTION_SPECIFICATION.UDSUBTYPE = MASS_TXNS.UDSUBTYPE "
4903
         "ORDER BY "
4904
            "SEQ_NO",
4905
         testScenario.getScenarioNumber() );
4906
      query->SQL->Text = sqlStatement;
4907
      query->Open();
4908
 
4909
      TransactionSpecification * transaction = 0;
4910
      while ( !query->Eof )
4911
      {
4912
         transaction = &testScenario.getTransactionSpecification(
4913
               query->FieldByName( "TXNSPEC_NO" )->AsInteger,
4914
               query->FieldByName( "NAME" )->AsString.c_str() );
4915
         transaction->setUdType(
4916
            query->FieldByName( "UDTYPE" )->AsInteger );
4917
         transaction->setUdSubtype(
4918
            query->FieldByName( "UDSUBTYPE" )->AsInteger );
4919
 
4920
         buildExecutionSchedule( *transaction );
4921
 
4922
         query->Next();
4923
      }
4924
   }
4925
   __finally
4926
   {
4927
      delete query;
4928
      query = 0;
4929
   }
4930
}
4931
//---------------------------------------------------------------------------
4932
 
4933
void __fastcall TMainForm::buildExecutionSchedule(
4934
               Iteration &       iteration,
4935
               const std::string &  testcaseId )
4936
{
4937
   TADOQuery * query = 0;
4938
   try
4939
   {
4940
      query = new TADOQuery( this );
4941
      query->Connection = Data_Module->IntegrationDBConnection;
4942
 
4943
      AnsiString sqlStatement;
4944
      sqlStatement.sprintf(
4945
         "SELECT "
4946
            "TESTSCENARIO_NO,"
4947
            "REPEAT_COUNT,"
4948
            "BATCH_SIZE,"
4949
            "NAME "
4950
         "FROM "
4951
            "TEST_SCENARIOS "
4952
         "WHERE "
4953
            "TESTCASE_ID=\'%s\' AND "
4954
            "PROJECT_CODE=\'%s\' AND "
4955
            "ITERATION=%d "
4956
         "ORDER BY "
4957
            "TESTCASE_SEQNO",
4958
         Utilities::EscapeString( testcaseId ).c_str(),
4959
         Utilities::EscapeString( iteration.getProjectCode() ).c_str(),
4960
         iteration.getIterationId() );
4961
      query->SQL->Text = sqlStatement;
4962
      query->Open();
4963
 
4964
      TestScenario * scenario = 0;
4965
      while ( !query->Eof )
4966
      {
4967
         scenario = &iteration.getTestScenario(
4968
            query->FieldByName( "TESTSCENARIO_NO" )->AsInteger );
4969
         /*
4970
         scenario->setBatchSize( 
4971
            !query->FieldByName( "BATCH_SIZE" )->IsNull
4972
               ? query->FieldByName( "BATCH_SIZE" )->AsInteger
4973
               : 0 );
4974
         */
4975
         scenario->setBatchSize( 99 );
4976
         scenario->setRepeatCount(
4977
            !query->FieldByName( "REPEAT_COUNT" )->IsNull
4978
               ? query->FieldByName( "REPEAT_COUNT" )->AsInteger
4979
               : 1 );
4980
         scenario->setScenarioName(
4981
            query->FieldByName( "NAME" )->AsString.c_str() );
4982
 
4983
         buildExecutionSchedule( *scenario );
4984
 
4985
         query->Next();
4986
      }
4987
   }
4988
   __finally
4989
   {
4990
      delete query;
4991
      query = 0;
4992
   }
4993
}
4994
//---------------------------------------------------------------------------
4995
 
4996
void __fastcall TMainForm::generateTransaction( std::vector< int > & scenarios )
4997
{
4998
//    GenerationPropertiesForm->Visible = true;
4999
//    GenerationPropertiesForm->SendToBack();
5000
   if ( GenerationPropertiesForm->ShowModal() == mrOk )
5001
   {
5002
      const bool           generateHeaders   = GenerationPropertiesForm->GenerateHeadersCheckBox->Checked;
5003
      const std::string    folder         = GenerationPropertiesForm->GenerationFolderDirectoryEdit->Text.c_str();
5004
      const std::string    batchPrefix    = GenerationPropertiesForm->DrainFilePrefixEdit->Text.c_str();
5005
      const std::string    batchSuffix    = GenerationPropertiesForm->DrainFileSuffixEdit->Text.c_str();
5006
      //const bool           buildManifest  = GenerationPropertiesForm->BuildManifestCheckBox->Checked;
5007
      //const std::string    manifestPrefix = GenerationPropertiesForm->ManifestPrefixEdit->Text.c_str();
5008
      //const std::string    manifestSuffix = GenerationPropertiesForm->ManifestSuffixEdit->Text.c_str();
5009
      const std::string    securityServer = GenerationPropertiesForm->SecurityServerPipeEdit->Text.c_str();
5010
      const unsigned short keyNumber      = GenerationPropertiesForm->KeyNumberEdit->Text.ToInt();
5011
      const unsigned short keyVersion     = GenerationPropertiesForm->KeyVersionEdit->Text.ToInt();
5012
      const std::string    pathmapTarget  = GenerationPropertiesForm->PathmapTargetEdit->Text.c_str();
5013
      const int            macAlgorithm   = GenerationPropertiesForm->MacAlgorithmComboBox->ItemIndex;
5014
 
5015
      GenerationPropertiesForm->Visible = false;
5016
 
5017
      AnsiString testCase = TestCaseQuery->FieldByName( "TESTCASE_ID" )->AsString;
5018
      const std::string    manifestPrefix =  testCase.c_str(); 
5019
      const std::string    manifestSuffix = ".txt";
5020
      const bool           buildManifest = true;  
5021
 
5022
 
5023
      /**
5024
         Create a transaction stream into our generation folder, and generate
5025
         the transactions into it.  We need to know whether we have to prepend
5026
         header (i.e., whether it is a .xdr which has a header, or a .devud which
5027
         doesn't).
5028
       */
5029
 
5030
      const TCursor           Save_Cursor             = Screen->Cursor;
5031
      bool                 transactionOpen            = false;
5032
      ICryptographicServerProxy *   cryptographicServerProxy   = 0;
5033
      IMessageDigest *        messageDigest           = 0;
5034
      IHash *                 hash                 = 0;
5035
 
5036
      AnsiString message;
5037
 
5038
      try
5039
      {
5040
         // firstly prepare for crypto MAC
5041
         if ( m_securityWrapperFactory )
5042
         {
5043
            cryptographicServerProxy = m_securityWrapperFactory
5044
               ->createCryptographicServerProxy( securityServer.c_str() );
5045
            if ( cryptographicServerProxy )
5046
            {
5047
               if ( cryptographicServerProxy->getModuleCount() )
5048
               {
5049
                  /**
5050
                   * We don't know which module will be used to compute the
5051
                   * MAC (security doesn't tell us), so until they do we
5052
                   * assume its the first module.
5053
                   */
5054
                  const unsigned int serialNumber =
5055
                  cryptographicServerProxy->getSerialNumber( 0 );
5056
 
5057
                  /**
5058
                     We now need to turn the 4-byte serial number into an
5059
                     8-byte diversifier.  Apparently, we must do this by
5060
                     writing the serial number into the lower 4-bytes in big
5061
                     endian.  An API is being added to crypto to do this:
5062
                     until it is there we need to do it ourselves.
5063
                   */
5064
                  unsigned char buffer[ 8 ];
5065
 
5066
                  buffer[ 0 ] = 0;
5067
                  buffer[ 1 ] = 0;
5068
                  buffer[ 2 ] = 0;
5069
                  buffer[ 3 ] = 0;
5070
                  buffer[ 4 ] = ( serialNumber >> 24 ) & 0xFF;
5071
                  buffer[ 5 ] = ( serialNumber >> 16 ) & 0xFF;
5072
                  buffer[ 6 ] = ( serialNumber >>  8 ) & 0xFF;
5073
                  buffer[ 7 ] = ( serialNumber       ) & 0xFF;
5074
 
5075
                  messageDigest = m_securityWrapperFactory
5076
                     ->createMessageDigest(
5077
                        *cryptographicServerProxy,
5078
                        keyNumber,
5079
                        keyVersion,
5080
                        buffer,
5081
                        sizeof( buffer ) );
5082
                  /**
5083
                   * If we need to compute the MAC by computing the MAC
5084
                   * of the SHA-1 hash, then we create the hash object
5085
                   * here.
5086
                   */
5087
                  if ( macAlgorithm == 1 )
5088
                  {
5089
                     hash = m_securityWrapperFactory->createHash();
5090
                  }
5091
               }
5092
               else
5093
               {
5094
                  MWARNING( "Cryptographic server has no modules." );
5095
               }
5096
            }
5097
         }
5098
 
5099
         Screen->Cursor = crHourGlass;
5100
         Data_Module->IntegrationDBConnection->BeginTrans();
5101
         transactionOpen = true;
5102
 
5103
         TransactionStream stream(folder, batchPrefix, batchSuffix, buildManifest,
5104
                                  manifestPrefix, manifestSuffix, pathmapTarget );
5105
         Iteration iteration( m_currentproject.c_str(), m_currentiteration,
5106
                             *XMLSchema->GetSchemaWrapperFactory(),
5107
                             *XMLSchema->GetSchema(), m_schema_handle );
5108
         DefinedVariableTable definedVariableTable;
5109
         SequenceCollection      sequences;
5110
         TimeEstimate         timeEstimate( *MainStatusBar->Panels->Items[ 0 ] );
5111
         EvaluationContext    context(definedVariableTable, sequences, *m_progressBar,
5112
                                      messageDigest, hash, cryptographicServerProxy, timeEstimate );
5113
         buildExecutionSchedule( iteration, testCase.c_str() );
5114
         loadLegacyVariables( definedVariableTable, m_currentproject.c_str(), iteration );
5115
         readSequences( sequences, m_currentproject.c_str(), m_currentiteration );
5116
 
5117
         try
5118
         {
5119
            int      count    = 0;
5120
            bool     generated   = false;
5121
            time_t   startTime;
5122
 
5123
            if ( scenarios.empty() )
5124
            {
5125
               // generate for an entire test case
5126
               // first setup the environment
5127
               count = iteration.getTransactionCount();
5128
               iteration.setBatchSize (TestCaseQuery->FieldByName( "BATCH_SIZE" )->Text.ToInt());
5129
               iteration.setTestCaseName (m_currenttestcaseid.c_str());
5130
               iteration.setCaseRepeat (m_currentcaserepeat);
5131
               iteration.setRepeatDelay (m_currentcasedelay);
5132
 
5133
               // now preapre the log file   and progress bars
5134
               message = DateToStr(Date());
5135
               stream.logToManifest (message.c_str(), false);
5136
               message = "Generating for Test Case " + testCase
5137
                                     + ". " +  TestCaseQuery->FieldByName( "NAME" )->AsString ;
5138
               stream.logToManifest (message.c_str(), false);
5139
               message.sprintf("Each run will create %d transactions with batch size of %d",count,iteration.getBatchSize());
5140
               stream.logToManifest (message.c_str(), false);
5141
               m_progressBar->open( count );
5142
               timeEstimate.start( count  );
5143
 
5144
               // now run the testcase multiple times
5145
               generated = true;
5146
               for ( int repeat = 1; repeat <= m_currentcaserepeat && generated; ++repeat )
5147
               {
5148
                  // first more logging and status bar info
5149
                  stream.logToManifest (" ", false);
5150
                  message.sprintf("run %d of %d started.",repeat,m_currentcaserepeat);
5151
                  stream.logToManifest (message.c_str(), true);
5152
                  message.sprintf("%s: run %d of %d in progress.  %d transactions with batch size of %d",
5153
                                  m_currenttestcaseid.c_str(),repeat,m_currentcaserepeat,count, iteration.getBatchSize());
5154
                  MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;  
5155
                  Application->ProcessMessages();
5156
 
5157
                  // now the real thing:  generate the test case 
5158
                  startTime = time(NULL);                              
5159
                  if (!iteration.generate( stream, generateHeaders, context ) )
5160
                  {  
5161
                     generated = false;
5162
                     break;
5163
                  }   
5164
 
5165
                  timeEstimate.stop();
5166
                  m_progressBar->close();       
5167
 
5168
 
5169
                  if (!generated)
5170
                  {
5171
                      // problems with the generation  ..  best we can do for now is report it in status bar and log
5172
                      message.sprintf("run %d encountered a problem." ,repeat);
5173
                      stream.logToManifest (message.c_str(), true);
5174
                      message.sprintf("%s: run %d of %d encountered a problem." ,
5175
                                          m_currenttestcaseid.c_str(),repeat, m_currentcaserepeat);
5176
                      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
5177
                      Application->ProcessMessages();
5178
                  }
5179
                  else
5180
                  {  
5181
                     // last run was good so check if we have to do it again
5182
                     // but first update log
5183
                     message.sprintf("run %d completed. Elapsed time for run was %d seconds" ,
5184
                                     repeat, time(NULL) - startTime);
5185
                     stream.logToManifest (message.c_str(), true);
5186
 
5187
                     if ( repeat < m_currentcaserepeat )
5188
                     {
5189
                        // do it again but possibly wait here before starting next session
5190
                        for (int delayRepeat = m_currentcasedelay - (time(NULL) - startTime); delayRepeat > 0 ; --delayRepeat)
5191
                        {                     
5192
                           message.sprintf("%s: run %d of %d completed.  Pausing generation for %d seconds" ,
5193
                                          m_currenttestcaseid.c_str(),repeat, m_currentcaserepeat, delayRepeat);
5194
                           MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
5195
                           Application->ProcessMessages();
5196
                           Sleep (1000);
5197
                        } 
5198
                     }
5199
                     else
5200
                     {
5201
                           // all done
5202
                           message.sprintf("%s: run %d of %d completed. " ,
5203
                                          m_currenttestcaseid.c_str(),repeat, m_currentcaserepeat);
5204
                           MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
5205
                           Application->ProcessMessages();               
5206
                     }
5207
                  }                      
5208
               }  
5209
            } // end of test case generation
5210
            else
5211
            {
5212
               // single test step generation
5213
               std::vector< int >::const_iterator where = scenarios.begin();
5214
               for ( where = scenarios.begin(); where != scenarios.end(); ++where )
5215
               {
5216
                  count += iteration.
5217
                  findTestScenario( *where ).getTransactionCount();
5218
               }
5219
 
5220
               // now preapre the log file   and progress bars
5221
               message = DateToStr(Date());
5222
               stream.logToManifest (message.c_str(), false);
5223
               message = "Generating for a single Test Step " ;
5224
               stream.logToManifest (message.c_str(), false);
5225
               message.sprintf("The step will create %d transactions with batch size of %d",count,iteration.getBatchSize());
5226
               stream.logToManifest (message.c_str(), false);               
5227
               m_progressBar->open( count );
5228
               timeEstimate.start( count );
5229
 
5230
               generated = true;
5231
               for ( where = scenarios.begin(); where != scenarios.end(); ++where )
5232
               {
5233
                 // first more logging and status bar info
5234
                  stream.logToManifest (" ", false);
5235
                  message.sprintf("test step started.");
5236
                  stream.logToManifest (message.c_str(), true);
5237
                  message.sprintf("test step generation in progress.  %d transactions with batch size of %d",
5238
                                  count, iteration.getBatchSize());
5239
                  MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;  
5240
                  Application->ProcessMessages();
5241
 
5242
                  // now the real thing:  generate the test step
5243
                  startTime = time(NULL);    
5244
                  if ( !iteration.findTestScenario( *where ).generate(
5245
                        stream,
5246
                        generateHeaders,
5247
                        context ) )
5248
                  {
5249
                     generated = false;
5250
                     // problems with the generation  ..  best we can do for now is report it in status bar and log
5251
                     message.sprintf("test step encountered a problem.");
5252
                     stream.logToManifest (message.c_str(), true);
5253
                     message.sprintf("generation for test step encountered a problem." );
5254
                     MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
5255
                     Application->ProcessMessages();  
5256
                     break;
5257
                  }
5258
                  else
5259
                  {
5260
                     // all done
5261
                     message.sprintf("test step completed.  Elapsed time for run was %d seconds",time(NULL) - startTime);
5262
                     stream.logToManifest (message.c_str(), true);
5263
                     message.sprintf("generation for test step completed." );
5264
                     MainStatusBar->Panels->Items[ g_messagePanel ]->Text = message;
5265
                     Application->ProcessMessages();                    
5266
                  }
5267
               }
5268
            }
5269
 
5270
            // generation complete so just finish off and tidy up
5271
            if ( generated )
5272
            {
5273
               writeSequences(
5274
                  sequences,
5275
                  m_currentproject.c_str(),
5276
                  m_currentiteration );
5277
 
5278
               Data_Module->IntegrationDBConnection->CommitTrans();
5279
               transactionOpen = false;
5280
            }
5281
         }
5282
         __finally
5283
         {
5284
            timeEstimate.stop();
5285
            m_progressBar->close();
5286
         }
5287
      }
5288
      __finally
5289
      {
5290
         if ( hash )
5291
         {
5292
            m_securityWrapperFactory->destroyHash( *hash );
5293
            hash = 0;
5294
         }
5295
         if ( messageDigest )
5296
         {
5297
            m_securityWrapperFactory
5298
               ->destroyMessageDigest( *messageDigest );
5299
            messageDigest = 0;
5300
         }
5301
         if ( cryptographicServerProxy )
5302
         {
5303
            m_securityWrapperFactory
5304
               ->destroyCryptographicServerProxy( *cryptographicServerProxy );
5305
            cryptographicServerProxy = 0;
5306
         }
5307
 
5308
         if ( transactionOpen )
5309
         {
5310
            Data_Module->IntegrationDBConnection->RollbackTrans();
5311
         }
5312
         Screen->Cursor = Save_Cursor;
5313
      }
5314
   }
5315
}
5316
//---------------------------------------------------------------------------
5317
 
5318
void __fastcall TMainForm::GenerateActionExecute(TObject *Sender)
5319
{
5320
   TTreeNode *       currentNode = 0;
5321
   std::vector< int >   scenarios;
5322
 
5323
   for ( unsigned selection=0;
5324
        selection<TestCaseTreeView->SelectionCount;
5325
        selection++ )
5326
   {
5327
      currentNode = TestCaseTreeView->Selections[ selection ];
5328
      if ( currentNode )
5329
      {
5330
         scenarios.push_back( reinterpret_cast< int >( currentNode->Data ) );
5331
      }
5332
   }
5333
   generateTransaction( scenarios );
5334
}
5335
//---------------------------------------------------------------------------
5336
 
5337
void __fastcall TMainForm::UdTransferBtnClick(TObject *Sender)
5338
{
5339
    UdTransferHistoryForm->Show();
5340
}
5341
//---------------------------------------------------------------------------
5342
 
5343
void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose)
5344
{
5345
    CanClose = true;
5346
 
5347
    // Warn if there are transfer tasks currently running
5348
 
5349
    if( (m_transferManager != NULL) &&
5350
        (m_transferManager->IsTaskRunning()) )
5351
    {
5352
        AnsiString msg = "There are UD transfers currently in progress. Quitting now will abort these tasks.";
5353
        msg += "\nAre you sure you want to continue?";
5354
        if( MessageDlg( msg, mtWarning, TMsgDlgButtons() << mbYes << mbNo, 0 ) == mrNo )
5355
        {
5356
            CanClose = false;
5357
        }
5358
    }
5359
}
5360
//---------------------------------------------------------------------------
5361
 
5362
 
5363
void __fastcall TMainForm::TestCaseTreeViewKeyUp(TObject *Sender,
5364
      WORD &Key, TShiftState Shift)
5365
{
5366
    if( Key == VK_DELETE )
5367
    {
5368
        bool deleteScenario = false;    
5369
        bool deleteTransaction = false;
5370
 
5371
        for( unsigned selected_item=0; selected_item<TestCaseTreeView->SelectionCount; selected_item++)
5372
        {
5373
            TTreeNode * current_node = TestCaseTreeView->Selections[selected_item];
5374
            if( current_node != NULL )
5375
            {
5376
                if( current_node->Level == 0 )
5377
                {
5378
                    deleteScenario = true;
5379
                }
5380
                else if( current_node->Level == 1 )
5381
                {
5382
                    deleteTransaction = true;
5383
                }
5384
            }
5385
        }
5386
        if( deleteScenario )
5387
        {
5388
            DeleteScenarioClick( Sender );
5389
        }
5390
        if( deleteTransaction )
5391
        {
5392
            DeleteTransactionActionExecute( Sender );
5393
        }
5394
    }
5395
}
5396
 
5397
//---------------------------------------------------------------------------
5398
 
5399
void __fastcall TMainForm::ValidateOldTestCaseCell(TObject *Sender, int OldRow,
5400
      int OldCol, int NewRow, int NewCol, bool &Allow)
5401
{
5402
      switch (OldCol)
5403
      {
5404
      case 3:  // Repeats
5405
      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "repeats finished";
5406
                  Application->ProcessMessages();
5407
      break;
5408
 
5409
      case 4: // period
5410
       MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "period finished" + DBAdvStringGrid2->Cells[OldCol][OldRow];
5411
                  Application->ProcessMessages();
5412
      if (StrToInt(DBAdvStringGrid2->Cells[OldCol][OldRow]) > 360)  DBAdvStringGrid2->Cells[OldCol][OldRow] = "360";
5413
      DBAdvStringGrid2->Cells[OldCol][OldRow] = "33"  ;
5414
 
5415
 //        TestCaseQuery->Post();
5416
      break;
5417
 
5418
      case 5: // batch
5419
      MainStatusBar->Panels->Items[ g_messagePanel ]->Text = "batch finished";  
5420
                  Application->ProcessMessages();
5421
      break;
5422
      }
5423
 
5424
 
5425
}
5426
//---------------------------------------------------------------------------
5427
//---------------------------------------------------------------------------
5428
 
5429
void __fastcall TMainForm::ExitClick(TObject *Sender)
5430
{
5431
    Close();
5432
}
5433