Subversion Repositories DevTools

Rev

Rev 2232 | Details | Compare with Previous | Last modification | View Log | RSS feed

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