Subversion Repositories DevTools

Rev

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