Subversion Repositories DevTools

Rev

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