Subversion Repositories DevTools

Rev

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