Subversion Repositories DevTools

Rev

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

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