Subversion Repositories DevTools

Rev

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