Subversion Repositories DevTools

Rev

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