os/persistentdata/persistentstorage/dbms/tdbms/t_dbscript.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <d32dbms.h>
sl@0
    17
#include <f32file.h>
sl@0
    18
#include <e32test.h>
sl@0
    19
#include <e32math.h>
sl@0
    20
#include <d32dbmsconstants.h>
sl@0
    21
sl@0
    22
LOCAL_D RTest TheTest(_L("t_dbscript"));
sl@0
    23
LOCAL_D CTrapCleanup* TheTrapCleanup;
sl@0
    24
LOCAL_D RDbNamedDatabase TheDatabase;
sl@0
    25
LOCAL_D RFs TheFs;
sl@0
    26
LOCAL_D RDbView TheView;
sl@0
    27
//
sl@0
    28
const TPtrC KTestDatabase=_L("c:\\dbms-tst\\t_script.db");
sl@0
    29
sl@0
    30
const TPtrC KRomScriptFile=_L("z:\\test\\t_script.txt");
sl@0
    31
sl@0
    32
const TPtrC KOutputFile=_L("c:\\dbms-tst\\t_script.log");
sl@0
    33
sl@0
    34
const TInt KTestCleanupStack=0x20;
sl@0
    35
const TPtrC KDDLKeywords[]={_L("CREATE"),_L("DROP"),_L("ALTER")};
sl@0
    36
const TPtrC KDMLKeywords[]={_L("INSERT"),_L("DELETE"),_L("UPDATE")};
sl@0
    37
const TPtrC KQueryKeywords[]={_L("SELECT")};
sl@0
    38
const TPtrC KScriptKeywords[]={_L("PRINT"),_L("ROWS"),_L("COMPARE"),_L("ERROR"),_L("!"),
sl@0
    39
							   _L("POPULATE"),_L("RESULTS"),_L("BUILD"),_L("QUERY"),
sl@0
    40
							   _L("NORMAL"),_L("FOLDED"),_L("COLLATED"),_L("START"),_L("STOP"),
sl@0
    41
							   _L("LOAD"),_L("ECHO"),_L("WINDOW"),_L("ACCESS")};
sl@0
    42
const TPtrC KRowIdColName=_L("Rw");
sl@0
    43
enum TKeyword {EPrint,ERows,ECompare,EError,EComment,EPopulate,EResults,EBuild,EQuery,ENormal,
sl@0
    44
               EFolded,ECollated,EStart,EStop,ELoad,EEcho,EWindow,EAccess,ENumKeywords,EUnknown};
sl@0
    45
//
sl@0
    46
typedef TBuf<256> TScriptLine;
sl@0
    47
typedef TBuf<256> TScriptToken;
sl@0
    48
//
sl@0
    49
#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
sl@0
    50
sl@0
    51
class TScript;
sl@0
    52
class TTimer
sl@0
    53
	{
sl@0
    54
public:
sl@0
    55
	inline TTimer(TScript& aScript);
sl@0
    56
	void Start(const TDesC& aDes);
sl@0
    57
	void Stop(const TDesC& aDes);
sl@0
    58
private:
sl@0
    59
	TUint iTicks;
sl@0
    60
	TScript& iScript;
sl@0
    61
	};
sl@0
    62
sl@0
    63
class TResults
sl@0
    64
	{
sl@0
    65
public:
sl@0
    66
	inline TResults();
sl@0
    67
public:
sl@0
    68
	RDbView& iView;
sl@0
    69
	TInt iError;
sl@0
    70
	TInt iRows;
sl@0
    71
	TInt iLineNo;
sl@0
    72
	TScriptLine iLine;
sl@0
    73
	};
sl@0
    74
sl@0
    75
class TSqlStatement
sl@0
    76
	{
sl@0
    77
private:
sl@0
    78
	enum TSqlType {EDML,EDDL,EQuery,EUnknown};
sl@0
    79
public:
sl@0
    80
	inline TSqlStatement(const TDesC& aSql,TResults& aResults);
sl@0
    81
	TInt Execute(TDbTextComparison aTextComparison=EDbCompareNormal,
sl@0
    82
		RDbRowSet::TAccess aAccess=RDbRowSet::EReadOnly,TBool aWindow=EFalse) const;
sl@0
    83
private:
sl@0
    84
	void ExecuteSql(TDbTextComparison aTextComparison) const;
sl@0
    85
	void ExecuteQuery(RDbRowSet::TAccess aAccess,TBool aWindow) const;
sl@0
    86
	TSqlType SqlType() const;
sl@0
    87
private:
sl@0
    88
	const TDesC& iSql;
sl@0
    89
	TResults& iResults;
sl@0
    90
	};
sl@0
    91
sl@0
    92
class TScript
sl@0
    93
	{
sl@0
    94
public:
sl@0
    95
	TScript();
sl@0
    96
	~TScript()
sl@0
    97
		{
sl@0
    98
		iFile.Close();
sl@0
    99
		}
sl@0
   100
	TInt ReadNextStatement();
sl@0
   101
	void GetNextTokenFromStatement(TDes& aToken);
sl@0
   102
	void GetNextTokenFromLine(TDes& aToken);
sl@0
   103
	TPtrC Statement();
sl@0
   104
	TInt IntValue();
sl@0
   105
	void WriteLine(const TDesC& aLine);
sl@0
   106
	void WriteError(const TDesC& aLine);
sl@0
   107
	void WriteSqlError(const TResults& aResults,const TDesC& aLine);
sl@0
   108
	void WriteComment(const TDesC& aLine);
sl@0
   109
	TKeyword Keyword(const TDesC& aKeyword) const;
sl@0
   110
	void ConsumeLine();
sl@0
   111
	void ConsumeStatement();
sl@0
   112
	inline TInt LineNo() const;
sl@0
   113
private:
sl@0
   114
	TInt ReadNextLine();
sl@0
   115
	TInt AppendNextLine();
sl@0
   116
	TBool IsStatement();
sl@0
   117
private:
sl@0
   118
	TFileText iInput;
sl@0
   119
	TFileText iOutput;
sl@0
   120
	TScriptLine iBuf;
sl@0
   121
	TLex iStatement;
sl@0
   122
	TLex iLine;
sl@0
   123
	TInt iLineNo;
sl@0
   124
	RFile iFile;
sl@0
   125
	};
sl@0
   126
sl@0
   127
class TScriptEngine
sl@0
   128
	{
sl@0
   129
public:
sl@0
   130
	inline TScriptEngine();
sl@0
   131
	void RunL();
sl@0
   132
private:
sl@0
   133
	void ExecuteL();
sl@0
   134
	TInt ExecuteScriptL();
sl@0
   135
	TInt ExecuteSql(const TDesC& aSql);
sl@0
   136
	TInt ExecuteSql();
sl@0
   137
	// keyword operations
sl@0
   138
	void DoPrintL();
sl@0
   139
	void DoComment();
sl@0
   140
	void DoError();
sl@0
   141
	void DoEcho();
sl@0
   142
	void DoWindow();
sl@0
   143
	void DoAccess();
sl@0
   144
	void DoRows();
sl@0
   145
	void DoCompareL();
sl@0
   146
	void DoPopulate();
sl@0
   147
	void DoResultsL();
sl@0
   148
	void DoBuildTable();
sl@0
   149
	void DoQuery();
sl@0
   150
	void DoTextComparison(TKeyword aKeyword);
sl@0
   151
	void DoStartTimer();
sl@0
   152
	void DoStopTimer();
sl@0
   153
	void DoLoadDb();
sl@0
   154
	//
sl@0
   155
	void PrintL(RDbRowSet& aRowSet);
sl@0
   156
	void CompareL(RDbRowSet& aRowSet);
sl@0
   157
	void CompareValues(RDbRowSet& aRowSet,TDbColNo ColNo,TDbColType aType,const TDesC& aToken);
sl@0
   158
	void FatalError(const TDesC& aLine);
sl@0
   159
	void FatalError();
sl@0
   160
	void FatalSqlError(const TDesC& aLine);
sl@0
   161
	void TestForNoError();
sl@0
   162
private:
sl@0
   163
	TScript iScript;
sl@0
   164
	TResults iResults;
sl@0
   165
	TDbTextComparison iTextComparison;
sl@0
   166
	TTimer iTimer;
sl@0
   167
	TBool iEcho;
sl@0
   168
	TBool iWindow;
sl@0
   169
	RDbRowSet::TAccess iAccess;
sl@0
   170
sl@0
   171
	};
sl@0
   172
sl@0
   173
//
sl@0
   174
// class TTimer
sl@0
   175
//
sl@0
   176
sl@0
   177
inline TTimer::TTimer(TScript& aScript)
sl@0
   178
	: iScript(aScript)
sl@0
   179
	{}
sl@0
   180
sl@0
   181
void TTimer::Start(const TDesC& aDes)
sl@0
   182
	{
sl@0
   183
	TScriptLine line;
sl@0
   184
	line.Format(_L("%S: "),&aDes);
sl@0
   185
	iScript.WriteLine(line);
sl@0
   186
	iTicks=User::TickCount();
sl@0
   187
	}
sl@0
   188
sl@0
   189
void TTimer::Stop(const TDesC& aDes)
sl@0
   190
	{
sl@0
   191
	TScriptLine line;
sl@0
   192
	line.Format(_L("%S: "),&aDes);
sl@0
   193
#ifdef __EPOC32__
sl@0
   194
#define TICK_TIME 15625
sl@0
   195
#else
sl@0
   196
#define	TICK_TIME 100000
sl@0
   197
#endif
sl@0
   198
	TInt microSec=(User::TickCount()-iTicks)*TICK_TIME;
sl@0
   199
	TUint sec=microSec/1000000;
sl@0
   200
	TUint centi=(microSec/10000)-sec*100;
sl@0
   201
	line.AppendFormat(_L("%u.%02us\n"),sec,centi);
sl@0
   202
	iScript.WriteLine(line);
sl@0
   203
	}
sl@0
   204
sl@0
   205
///////////////////////////////////////////////////////////////////////////////////////
sl@0
   206
sl@0
   207
LOCAL_C void DeleteDataFile(const TDesC& aFullName)
sl@0
   208
    {
sl@0
   209
    RFs fsSession;
sl@0
   210
    TInt err = fsSession.Connect();
sl@0
   211
    if(err == KErrNone)
sl@0
   212
        {
sl@0
   213
        TEntry entry;
sl@0
   214
        if(fsSession.Entry(aFullName, entry) == KErrNone)
sl@0
   215
            {
sl@0
   216
            RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
sl@0
   217
            err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
sl@0
   218
            if(err != KErrNone)
sl@0
   219
                {
sl@0
   220
                RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
sl@0
   221
                }
sl@0
   222
            err = fsSession.Delete(aFullName);
sl@0
   223
            if(err != KErrNone)
sl@0
   224
                {
sl@0
   225
                RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
sl@0
   226
                }
sl@0
   227
            }
sl@0
   228
        fsSession.Close();
sl@0
   229
        }
sl@0
   230
    else
sl@0
   231
        {
sl@0
   232
        RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
sl@0
   233
        }
sl@0
   234
    }
sl@0
   235
sl@0
   236
///////////////////////////////////////////////////////////////////////////////////////
sl@0
   237
///////////////////////////////////////////////////////////////////////////////////////
sl@0
   238
//Tests macros and functions.
sl@0
   239
//If (!aValue) then the test will be panicked, the test data files will be deleted.
sl@0
   240
static void Check(TInt aValue, TInt aLine)
sl@0
   241
    {
sl@0
   242
    if(!aValue)
sl@0
   243
        {
sl@0
   244
        RDebug::Print(_L("*** Expression evaluated to false\r\n"));
sl@0
   245
        DeleteDataFile(KTestDatabase);
sl@0
   246
        DeleteDataFile(KOutputFile);
sl@0
   247
        TheTest(EFalse, aLine);
sl@0
   248
        }
sl@0
   249
    }
sl@0
   250
//If (aValue != aExpected) then the test will be panicked, the test data files will be deleted.
sl@0
   251
static void Check(TInt aValue, TInt aExpected, TInt aLine)
sl@0
   252
    {
sl@0
   253
    if(aValue != aExpected)
sl@0
   254
        {
sl@0
   255
        RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
sl@0
   256
        DeleteDataFile(KTestDatabase);
sl@0
   257
        DeleteDataFile(KOutputFile);
sl@0
   258
        TheTest(EFalse, aLine);
sl@0
   259
        }
sl@0
   260
    }
sl@0
   261
//Use these to test conditions.
sl@0
   262
#define TEST(arg) Check((arg), __LINE__)
sl@0
   263
#define TEST2(aValue, aExpected) Check(aValue, aExpected, __LINE__)
sl@0
   264
sl@0
   265
///////////////////////////////////////////////////////////////////////////////////////
sl@0
   266
///////////////////////////////////////////////////////////////////////////////////////
sl@0
   267
sl@0
   268
//
sl@0
   269
// class TResults
sl@0
   270
//
sl@0
   271
sl@0
   272
inline TResults::TResults()
sl@0
   273
	: iView(TheView),iError(KErrNone)
sl@0
   274
	{}
sl@0
   275
sl@0
   276
sl@0
   277
//
sl@0
   278
// class TSqlStatement
sl@0
   279
//
sl@0
   280
sl@0
   281
inline TSqlStatement::TSqlStatement(const TDesC& aSql,TResults& aResults)
sl@0
   282
	: iSql(aSql),iResults(aResults)
sl@0
   283
	{}
sl@0
   284
sl@0
   285
//
sl@0
   286
// executes DML or DDL
sl@0
   287
//
sl@0
   288
void TSqlStatement::ExecuteSql(TDbTextComparison aTextComparison) const
sl@0
   289
	{
sl@0
   290
	TInt r=TheDatabase.Execute(iSql,aTextComparison);
sl@0
   291
	if (r<0)
sl@0
   292
		iResults.iError=r;
sl@0
   293
	else
sl@0
   294
		{
sl@0
   295
		iResults.iError=KErrNone;
sl@0
   296
		iResults.iRows=r;
sl@0
   297
		}
sl@0
   298
	}
sl@0
   299
sl@0
   300
void TSqlStatement::ExecuteQuery(RDbRowSet::TAccess aAccess,TBool aWindow) const
sl@0
   301
	{
sl@0
   302
	iResults.iView.Close();			// discard any previous queries
sl@0
   303
	TInt& err=iResults.iError;
sl@0
   304
	if (aWindow)
sl@0
   305
		err=iResults.iView.Prepare(TheDatabase,iSql,KDbUnlimitedWindow,aAccess);
sl@0
   306
	else
sl@0
   307
		err=iResults.iView.Prepare(TheDatabase,iSql,aAccess);
sl@0
   308
	if (err==KErrNone)
sl@0
   309
		err=iResults.iView.EvaluateAll();
sl@0
   310
	}
sl@0
   311
sl@0
   312
//
sl@0
   313
// determines the type of sql statement by matching keywords
sl@0
   314
//
sl@0
   315
TSqlStatement::TSqlType TSqlStatement::SqlType() const
sl@0
   316
	{
sl@0
   317
	for (TUint i=0;i<ARRAY_SIZE(KDDLKeywords);++i)
sl@0
   318
		{
sl@0
   319
		if (iSql.FindF(KDDLKeywords[i])==0)
sl@0
   320
			return EDDL;
sl@0
   321
		}
sl@0
   322
	for (TUint ii=0;ii<ARRAY_SIZE(KDMLKeywords);++ii)
sl@0
   323
		{
sl@0
   324
		if (iSql.FindF(KDMLKeywords[ii])==0)
sl@0
   325
			return EDML;
sl@0
   326
		}
sl@0
   327
	for (TUint j=0;j<ARRAY_SIZE(KQueryKeywords);++j)
sl@0
   328
		{
sl@0
   329
		if (iSql.FindF(KQueryKeywords[j])==0)
sl@0
   330
			return EQuery;
sl@0
   331
		}
sl@0
   332
	return EUnknown;
sl@0
   333
	}
sl@0
   334
sl@0
   335
//
sl@0
   336
// executes the sql statement
sl@0
   337
//
sl@0
   338
TInt TSqlStatement::Execute(TDbTextComparison aTextComparison,RDbRowSet::TAccess aAccess,TBool aWindow) const
sl@0
   339
	{
sl@0
   340
	TInt r=KErrNone;
sl@0
   341
	switch (SqlType())
sl@0
   342
		{
sl@0
   343
	case EDDL:
sl@0
   344
	case EDML:
sl@0
   345
		ExecuteSql(aTextComparison);
sl@0
   346
		break;
sl@0
   347
	case EQuery:
sl@0
   348
		ExecuteQuery(aAccess,aWindow);
sl@0
   349
		break;
sl@0
   350
	case EUnknown:
sl@0
   351
	default:
sl@0
   352
		r=KErrNotFound;
sl@0
   353
		break;
sl@0
   354
		}
sl@0
   355
	return r;
sl@0
   356
	}
sl@0
   357
sl@0
   358
sl@0
   359
//
sl@0
   360
// class TScript
sl@0
   361
//
sl@0
   362
sl@0
   363
TScript::TScript()
sl@0
   364
	: iLineNo(0)
sl@0
   365
	{
sl@0
   366
	TheTest.Printf(_L("---TScript::TScript(), Open the script file \"%S\"\r\n"), &KRomScriptFile);
sl@0
   367
	RFile file;
sl@0
   368
	TInt r=file.Open(TheFs, KRomScriptFile, EFileRead);
sl@0
   369
	TEST2(r, KErrNone);
sl@0
   370
	iInput.Set(file);
sl@0
   371
    TheTest.Printf(_L("---TScript::TScript(), Create the file \"%S\"\r\n"), &KOutputFile);
sl@0
   372
	TEST2(file.Replace(TheFs, KOutputFile, EFileWrite), KErrNone);
sl@0
   373
	iOutput.Set(file);
sl@0
   374
	iFile = file;
sl@0
   375
	}
sl@0
   376
sl@0
   377
inline TInt TScript::LineNo() const
sl@0
   378
	{return iLineNo;}
sl@0
   379
sl@0
   380
//
sl@0
   381
//  checks for keywords which possibly conform to the usual statement format (ie end in ';')
sl@0
   382
//
sl@0
   383
TBool TScript::IsStatement()
sl@0
   384
	{
sl@0
   385
	if (iLine.Remainder().Length()==0)	// null statement
sl@0
   386
		return ETrue;
sl@0
   387
	TPtrC line=iLine.Remainder();
sl@0
   388
	TKeyword keyword=Keyword(line);
sl@0
   389
	switch (keyword)
sl@0
   390
		{
sl@0
   391
	case EPrint:
sl@0
   392
	case ERows:
sl@0
   393
	case EBuild:
sl@0
   394
	case EError:
sl@0
   395
	case EQuery:
sl@0
   396
	case ENormal:
sl@0
   397
	case EFolded:
sl@0
   398
	case ECollated:
sl@0
   399
	case EStart:
sl@0
   400
	case EStop:
sl@0
   401
	case ELoad:
sl@0
   402
	case EEcho:
sl@0
   403
	case EWindow:
sl@0
   404
	case EAccess:
sl@0
   405
	case EUnknown:						// could be sql
sl@0
   406
		return ETrue;
sl@0
   407
	case EComment:
sl@0
   408
	case EPopulate:
sl@0
   409
	case ECompare:
sl@0
   410
	case EResults:
sl@0
   411
		iStatement=line;				// not a statement, so make it the whole line
sl@0
   412
		return EFalse;
sl@0
   413
	default:
sl@0
   414
		TEST(0);
sl@0
   415
		return EFalse;
sl@0
   416
		}
sl@0
   417
	}
sl@0
   418
sl@0
   419
//
sl@0
   420
// reads the next non-blank statement or line
sl@0
   421
//
sl@0
   422
TInt TScript::ReadNextStatement()
sl@0
   423
	{
sl@0
   424
	TInt r=ReadNextLine();
sl@0
   425
	if (r!=KErrNone || !IsStatement())
sl@0
   426
		return r;
sl@0
   427
	TChar c=0;
sl@0
   428
	while (c!=';')
sl@0
   429
		{
sl@0
   430
		c=iLine.Get();
sl@0
   431
		if (!c)							// nothing left to read
sl@0
   432
			{
sl@0
   433
			r=AppendNextLine();
sl@0
   434
			if (r!=KErrNone)
sl@0
   435
				return r;
sl@0
   436
			}
sl@0
   437
		}
sl@0
   438
	iLine.UnGet();						// the semi-colon
sl@0
   439
	iStatement=iLine.MarkedToken();
sl@0
   440
	iLine.Get();						// the semi-colon
sl@0
   441
	iLine.SkipSpaceAndMark();
sl@0
   442
	return KErrNone;
sl@0
   443
	}
sl@0
   444
sl@0
   445
TPtrC TScript::Statement()
sl@0
   446
	{
sl@0
   447
	return iStatement.Remainder();
sl@0
   448
	}
sl@0
   449
sl@0
   450
void TScript::ConsumeLine()
sl@0
   451
	{
sl@0
   452
	iLine=TPtrC();
sl@0
   453
	iStatement=TPtrC();
sl@0
   454
	}
sl@0
   455
sl@0
   456
void TScript::ConsumeStatement()
sl@0
   457
	{
sl@0
   458
	iLine=iLine.Remainder();
sl@0
   459
	iStatement=TPtrC();
sl@0
   460
	}
sl@0
   461
sl@0
   462
//
sl@0
   463
// reads the next non-blank line into iLine
sl@0
   464
//
sl@0
   465
TInt TScript::ReadNextLine()
sl@0
   466
	{
sl@0
   467
	while (iLine.Remainder().Length()==0)
sl@0
   468
		{
sl@0
   469
		TInt r=iInput.Read(iBuf);
sl@0
   470
		if (r!=KErrNone)
sl@0
   471
			return r;
sl@0
   472
		if (iBuf.Length()>0 && iBuf[0]==0xfeff)	// unicode stream marker
sl@0
   473
			iBuf.Delete(0,1);
sl@0
   474
		iLineNo++;
sl@0
   475
		iLine=iBuf;
sl@0
   476
		iLine.SkipSpaceAndMark();
sl@0
   477
		}
sl@0
   478
	return KErrNone;
sl@0
   479
	}
sl@0
   480
sl@0
   481
//
sl@0
   482
// adds next line from file to iLine
sl@0
   483
//
sl@0
   484
TInt TScript::AppendNextLine()
sl@0
   485
	{
sl@0
   486
	TScriptLine line;
sl@0
   487
	do {
sl@0
   488
		TInt r=iInput.Read(line);
sl@0
   489
		if (r!=KErrNone)
sl@0
   490
			return r;
sl@0
   491
		iLineNo++;
sl@0
   492
		} while (line.Length()==0);
sl@0
   493
	iBuf=iLine.MarkedToken();
sl@0
   494
	iBuf.Append(line);
sl@0
   495
	iLine=iBuf;
sl@0
   496
	return KErrNone;
sl@0
   497
	}
sl@0
   498
sl@0
   499
void TScript::WriteError(const TDesC& aLine)
sl@0
   500
	{
sl@0
   501
	TScriptLine line;
sl@0
   502
	line.Format(_L("Error at line %d: %S\n"),iLineNo,&aLine);
sl@0
   503
	WriteLine(line);
sl@0
   504
	TheTest.Printf(line);
sl@0
   505
	}
sl@0
   506
sl@0
   507
void TScript::WriteSqlError(const TResults& aResults,const TDesC& aLine)
sl@0
   508
	{
sl@0
   509
	TScriptLine line;
sl@0
   510
	line.Format(_L("Error at line %d: %S :-\n"),aResults.iLineNo,&aLine);
sl@0
   511
	WriteLine(line);
sl@0
   512
	TheTest.Printf(line);
sl@0
   513
	line.Format(_L("\t%S\n"),&aResults.iLine);
sl@0
   514
	WriteLine(line);
sl@0
   515
	TheTest.Printf(line);
sl@0
   516
	}
sl@0
   517
sl@0
   518
void TScript::WriteLine(const TDesC& aLine)
sl@0
   519
	{
sl@0
   520
	TScriptLine l=aLine;
sl@0
   521
	l.Append('\r');
sl@0
   522
	iOutput.Write(l);
sl@0
   523
	}
sl@0
   524
sl@0
   525
void TScript::WriteComment(const TDesC& aLine)
sl@0
   526
	{
sl@0
   527
	TScriptLine line;
sl@0
   528
	line.Format(_L("\n%S"),&aLine);
sl@0
   529
	WriteLine(line);
sl@0
   530
	}
sl@0
   531
sl@0
   532
//
sl@0
   533
// returns the integer n from the ' = n ' which must follow in the statement
sl@0
   534
//
sl@0
   535
TInt TScript::IntValue()
sl@0
   536
	{
sl@0
   537
	TScriptToken keyword;
sl@0
   538
	GetNextTokenFromStatement(keyword);
sl@0
   539
	if (keyword.Compare(_L("="))!=0)
sl@0
   540
		WriteError(_L("expected '=' missing"));
sl@0
   541
	iStatement.SkipSpaceAndMark();
sl@0
   542
	TInt num=0;
sl@0
   543
	TInt err=iStatement.Val(num);
sl@0
   544
	if (err!=KErrNone)
sl@0
   545
		WriteError(_L("expected number missing"));
sl@0
   546
	return num;
sl@0
   547
	}
sl@0
   548
sl@0
   549
TKeyword TScript::Keyword(const TDesC& aKeyword) const
sl@0
   550
	{
sl@0
   551
	for (TInt ii=0; ii<ENumKeywords; ++ii)
sl@0
   552
		{
sl@0
   553
		if (aKeyword.FindF(KScriptKeywords[ii])==0)
sl@0
   554
			return TKeyword(ii);
sl@0
   555
		}
sl@0
   556
	return EUnknown;
sl@0
   557
	}
sl@0
   558
sl@0
   559
//
sl@0
   560
// gets the next token from iStatement
sl@0
   561
//
sl@0
   562
void TScript::GetNextTokenFromStatement(TDes& aToken)
sl@0
   563
	{
sl@0
   564
	iStatement.SkipSpaceAndMark();
sl@0
   565
	TUint c;
sl@0
   566
	do
sl@0
   567
		{
sl@0
   568
		c=iStatement.Get();
sl@0
   569
		if (c=='=' || c=='!')
sl@0
   570
			break;
sl@0
   571
		} while (iStatement.Peek().IsAlphaDigit());
sl@0
   572
	aToken=iStatement.MarkedToken();
sl@0
   573
	iStatement.SkipSpaceAndMark();
sl@0
   574
	}
sl@0
   575
sl@0
   576
//
sl@0
   577
// gets the next token from iLine
sl@0
   578
//
sl@0
   579
void TScript::GetNextTokenFromLine(TDes& aToken)
sl@0
   580
	{
sl@0
   581
	iLine.SkipSpaceAndMark();
sl@0
   582
	TUint c=0;
sl@0
   583
	TChar cc=c;
sl@0
   584
	TBool literal=EFalse;
sl@0
   585
	do
sl@0
   586
		{
sl@0
   587
		c=iLine.Get();
sl@0
   588
		if (!c)
sl@0
   589
			{
sl@0
   590
			AppendNextLine();
sl@0
   591
			iLine.SkipSpaceAndMark();
sl@0
   592
			c=iLine.Get();
sl@0
   593
			}
sl@0
   594
		if (c=='\'' || c=='#')
sl@0
   595
			literal=!literal;
sl@0
   596
		if ((c==',' || c=='(' || c==')' || c=='{' || c=='}' || c=='!' ) && !literal)
sl@0
   597
			break;
sl@0
   598
		cc=iLine.Peek();
sl@0
   599
		} while (cc.IsAlphaDigit() || literal || TUint(cc)=='.' || TUint(cc)=='+' || TUint(cc)=='-');
sl@0
   600
	aToken=iLine.MarkedToken();
sl@0
   601
	if (TUint(cc)==';')					// ignore semi-colons - they're optional
sl@0
   602
		iLine.Get();
sl@0
   603
	iLine.SkipSpaceAndMark();
sl@0
   604
	if (c=='!')
sl@0
   605
		{
sl@0
   606
		iStatement=iLine.Remainder();
sl@0
   607
		TPtrC comment=iStatement.Remainder();
sl@0
   608
		WriteComment(comment);
sl@0
   609
		iLine=TPtrC();
sl@0
   610
		GetNextTokenFromLine(aToken);
sl@0
   611
		}
sl@0
   612
	}
sl@0
   613
sl@0
   614
sl@0
   615
//
sl@0
   616
// class TScriptEngine
sl@0
   617
//
sl@0
   618
sl@0
   619
TScriptEngine::TScriptEngine()
sl@0
   620
	: iTextComparison(EDbCompareNormal),iTimer(iScript),iEcho(EFalse),iWindow(EFalse),iAccess(RDbRowSet::EReadOnly)
sl@0
   621
	{}
sl@0
   622
sl@0
   623
sl@0
   624
//
sl@0
   625
// runs the script file
sl@0
   626
//
sl@0
   627
void TScriptEngine::RunL()
sl@0
   628
	{
sl@0
   629
	while (iScript.ReadNextStatement()!=KErrEof)
sl@0
   630
		ExecuteL();
sl@0
   631
	TestForNoError();
sl@0
   632
	}
sl@0
   633
sl@0
   634
void TScriptEngine::TestForNoError()
sl@0
   635
	{
sl@0
   636
	if (iResults.iError!=KErrNone)
sl@0
   637
		{
sl@0
   638
		TScriptLine line;
sl@0
   639
		line.Format(_L("unexpected error %d"),iResults.iError);
sl@0
   640
		FatalSqlError(line);
sl@0
   641
		}
sl@0
   642
	}
sl@0
   643
sl@0
   644
void TScriptEngine::ExecuteL()
sl@0
   645
	{
sl@0
   646
	if (ExecuteScriptL()!=KErrNone && ExecuteSql()!=KErrNone)
sl@0
   647
		FatalSqlError(_L("syntax error"));
sl@0
   648
	}
sl@0
   649
sl@0
   650
TInt TScriptEngine::ExecuteScriptL()
sl@0
   651
	{
sl@0
   652
	TKeyword keyword=iScript.Keyword(iScript.Statement());
sl@0
   653
	if (keyword!=EError)
sl@0
   654
		TestForNoError();
sl@0
   655
	switch (keyword)
sl@0
   656
		{
sl@0
   657
	case EPrint:
sl@0
   658
		DoPrintL();
sl@0
   659
		break;
sl@0
   660
	case ERows:
sl@0
   661
		DoRows();
sl@0
   662
		break;
sl@0
   663
	case ELoad:
sl@0
   664
		DoLoadDb();
sl@0
   665
		break;
sl@0
   666
	case EEcho:
sl@0
   667
		DoEcho();
sl@0
   668
		break;
sl@0
   669
	case EWindow:
sl@0
   670
		DoWindow();
sl@0
   671
		break;
sl@0
   672
	case EAccess:
sl@0
   673
		DoAccess();
sl@0
   674
		break;
sl@0
   675
	case ECompare:
sl@0
   676
		DoCompareL();
sl@0
   677
		break;
sl@0
   678
	case EError:
sl@0
   679
		DoError();
sl@0
   680
		break;
sl@0
   681
	case EPopulate:
sl@0
   682
		DoPopulate();
sl@0
   683
		break;
sl@0
   684
	case EComment:
sl@0
   685
		DoComment();
sl@0
   686
		break;
sl@0
   687
	case EResults:
sl@0
   688
		DoResultsL();
sl@0
   689
		break;
sl@0
   690
	case EBuild:
sl@0
   691
		DoBuildTable();
sl@0
   692
		break;
sl@0
   693
	case EQuery:
sl@0
   694
		DoQuery();
sl@0
   695
		break;
sl@0
   696
	case ENormal:
sl@0
   697
	case EFolded:
sl@0
   698
	case ECollated:
sl@0
   699
		DoTextComparison(keyword);
sl@0
   700
		break;
sl@0
   701
	case EStart:
sl@0
   702
		DoStartTimer();
sl@0
   703
		break;
sl@0
   704
	case EStop:
sl@0
   705
		DoStopTimer();
sl@0
   706
		break;
sl@0
   707
	case EUnknown:
sl@0
   708
	default:
sl@0
   709
		return KErrNotFound;
sl@0
   710
		}
sl@0
   711
	return KErrNone;
sl@0
   712
	}
sl@0
   713
sl@0
   714
TInt TScriptEngine::ExecuteSql()
sl@0
   715
	{
sl@0
   716
	return ExecuteSql(iScript.Statement());
sl@0
   717
	}
sl@0
   718
sl@0
   719
TInt TScriptEngine::ExecuteSql(const TDesC& aSql)
sl@0
   720
	{
sl@0
   721
	if (iEcho)
sl@0
   722
		{
sl@0
   723
		TScriptLine line(_L("\nSQL:\t"));
sl@0
   724
		line.Append(aSql);
sl@0
   725
		iScript.WriteLine(line);
sl@0
   726
		}
sl@0
   727
	iResults.iLineNo=iScript.LineNo();
sl@0
   728
	iResults.iLine=aSql;
sl@0
   729
	TSqlStatement statement(aSql,iResults);
sl@0
   730
	return statement.Execute(iTextComparison,iAccess,iWindow);
sl@0
   731
	}
sl@0
   732
sl@0
   733
void TScriptEngine::DoStartTimer()
sl@0
   734
	{
sl@0
   735
	// test its right function
sl@0
   736
	TScriptToken keyword;
sl@0
   737
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   738
	TEST2(keyword.CompareF(_L("START")), 0);
sl@0
   739
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   740
	TEST2(keyword.CompareF(_L("TIMER")), 0);
sl@0
   741
	//
sl@0
   742
	iTimer.Start(_L("Timer started"));
sl@0
   743
	}
sl@0
   744
sl@0
   745
void TScriptEngine::DoStopTimer()
sl@0
   746
	{
sl@0
   747
	// test its right function
sl@0
   748
	TScriptToken keyword;
sl@0
   749
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   750
	TEST2(keyword.CompareF(_L("STOP")), 0);
sl@0
   751
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   752
	TEST2(keyword.CompareF(_L("TIMER")), 0);
sl@0
   753
	//
sl@0
   754
	iTimer.Stop(_L("Timer stopped"));
sl@0
   755
	}
sl@0
   756
sl@0
   757
void TScriptEngine::DoTextComparison(TKeyword aKeyword)
sl@0
   758
	{
sl@0
   759
	TPtrC line;
sl@0
   760
	switch (aKeyword)
sl@0
   761
		{
sl@0
   762
	case ENormal:
sl@0
   763
		iTextComparison=EDbCompareNormal;
sl@0
   764
		line.Set(_L("[Normal text comparison]"));
sl@0
   765
		break;
sl@0
   766
	case EFolded:
sl@0
   767
		iTextComparison=EDbCompareFolded;
sl@0
   768
		line.Set(_L("[Folded text comparison]"));
sl@0
   769
		break;
sl@0
   770
	case ECollated:
sl@0
   771
		iTextComparison=EDbCompareCollated;
sl@0
   772
		line.Set(_L("[Collated text comparison]"));
sl@0
   773
		break;
sl@0
   774
	default:
sl@0
   775
		TEST(0);
sl@0
   776
		}
sl@0
   777
	iScript.WriteLine(line);
sl@0
   778
	}
sl@0
   779
sl@0
   780
void TScriptEngine::DoComment()
sl@0
   781
	{
sl@0
   782
	// test its right function
sl@0
   783
	TScriptToken keyword;
sl@0
   784
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   785
	TEST2(keyword.CompareF(_L("!")), 0);
sl@0
   786
	//
sl@0
   787
	TPtrC comment=iScript.Statement();
sl@0
   788
	iScript.WriteComment(comment);
sl@0
   789
	iScript.ConsumeLine();
sl@0
   790
	}
sl@0
   791
sl@0
   792
void TScriptEngine::DoError()
sl@0
   793
	{
sl@0
   794
	// test its right function
sl@0
   795
	TScriptToken keyword;
sl@0
   796
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   797
	TEST2(keyword.CompareF(_L("ERROR")), 0);
sl@0
   798
	//
sl@0
   799
	TScriptLine line;
sl@0
   800
	if (iScript.Statement().Length()==0)
sl@0
   801
		{
sl@0
   802
		if (iResults.iError>=0)
sl@0
   803
			FatalSqlError(_L("no error when one was expected"));
sl@0
   804
		line=_L("\t\tERROR OK");
sl@0
   805
		}
sl@0
   806
	else
sl@0
   807
		{
sl@0
   808
		TInt err=iScript.IntValue();
sl@0
   809
		if (iResults.iError!=err)
sl@0
   810
			{
sl@0
   811
			line.Format(_L("expected error %d, actual error %d"),err,iResults.iError);
sl@0
   812
			FatalSqlError(line);
sl@0
   813
			}
sl@0
   814
		line.Format(_L("\t\tERROR=%D OK"),err);
sl@0
   815
		}
sl@0
   816
	iResults.iError=0;
sl@0
   817
	iScript.WriteLine(line);
sl@0
   818
	}
sl@0
   819
sl@0
   820
void TScriptEngine::DoRows()
sl@0
   821
	{
sl@0
   822
	// test its right function
sl@0
   823
	TScriptToken keyword;
sl@0
   824
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   825
	TEST2(keyword.CompareF(_L("ROWS")), 0);
sl@0
   826
	//
sl@0
   827
	TScriptLine line;
sl@0
   828
	TInt rows=iScript.IntValue();
sl@0
   829
	if (iResults.iRows!=rows)
sl@0
   830
		{
sl@0
   831
		line.Format(_L("expected rows %d, actual rows %d"),rows,iResults.iRows);
sl@0
   832
		FatalSqlError(line);
sl@0
   833
		}
sl@0
   834
	line.Format(_L("\t\tROWS=%D OK"),rows);
sl@0
   835
	iScript.WriteLine(line);
sl@0
   836
	}
sl@0
   837
sl@0
   838
void TScriptEngine::DoLoadDb()
sl@0
   839
	{
sl@0
   840
	// test its right function
sl@0
   841
	TScriptToken token;
sl@0
   842
	iScript.GetNextTokenFromStatement(token);
sl@0
   843
	TEST2(token.CompareF(_L("LOAD")), 0);
sl@0
   844
	//
sl@0
   845
	TFileName database(iScript.Statement());
sl@0
   846
	TheDatabase.Close();
sl@0
   847
	TScriptLine line;
sl@0
   848
	line.Format(_L("Opening database: %S"),&database);
sl@0
   849
	iScript.WriteLine(line);
sl@0
   850
	TEST2(TheDatabase.Open(TheFs,database), KErrNone);
sl@0
   851
	}
sl@0
   852
sl@0
   853
void TScriptEngine::DoEcho()
sl@0
   854
	{
sl@0
   855
	// test its right function
sl@0
   856
	TScriptToken keyword;
sl@0
   857
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   858
	TEST2(keyword.CompareF(_L("ECHO")), 0);
sl@0
   859
	//
sl@0
   860
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   861
	if (keyword.CompareF(_L("OFF"))==0)
sl@0
   862
		{
sl@0
   863
		iEcho=EFalse;
sl@0
   864
		iScript.WriteLine(_L("Echo is off"));
sl@0
   865
		}
sl@0
   866
	else if (keyword.CompareF(_L("ON"))==0)
sl@0
   867
		{
sl@0
   868
		iEcho=ETrue;
sl@0
   869
		iScript.WriteLine(_L("Echo is on"));
sl@0
   870
		}
sl@0
   871
	else
sl@0
   872
		FatalError(_L("Expected ON|OFF to follow ECHO statement"));
sl@0
   873
	}
sl@0
   874
sl@0
   875
void TScriptEngine::DoWindow()
sl@0
   876
	{
sl@0
   877
	// test its right function
sl@0
   878
	TScriptToken keyword;
sl@0
   879
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   880
	TEST2(keyword.CompareF(_L("WINDOW")), 0);
sl@0
   881
	//
sl@0
   882
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   883
	if (keyword.CompareF(_L("OFF"))==0)
sl@0
   884
		{
sl@0
   885
		iWindow=EFalse;
sl@0
   886
		iScript.WriteLine(_L("Window is off"));
sl@0
   887
		}
sl@0
   888
	else if (keyword.CompareF(_L("ON"))==0)
sl@0
   889
		{
sl@0
   890
		iWindow=ETrue;
sl@0
   891
		iScript.WriteLine(_L("Window is on"));
sl@0
   892
		}
sl@0
   893
	else
sl@0
   894
		FatalError(_L("Expected ON|OFF to follow WINDOW statement"));
sl@0
   895
	}
sl@0
   896
sl@0
   897
void TScriptEngine::DoAccess()
sl@0
   898
	{
sl@0
   899
	// test its right function
sl@0
   900
	TScriptToken keyword;
sl@0
   901
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   902
	TEST2(keyword.CompareF(_L("ACCESS")), 0);
sl@0
   903
	//
sl@0
   904
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   905
	if (keyword.CompareF(_L("UPDATE"))==0)
sl@0
   906
		{
sl@0
   907
		iAccess=RDbRowSet::EUpdatable;
sl@0
   908
		iScript.WriteLine(_L("Access is updateable"));
sl@0
   909
		}
sl@0
   910
	else if (keyword.CompareF(_L("READ"))==0)
sl@0
   911
		{
sl@0
   912
		iAccess=RDbRowSet::EReadOnly;
sl@0
   913
		iScript.WriteLine(_L("Access is read only"));
sl@0
   914
		}
sl@0
   915
	else if (keyword.CompareF(_L("INSERT"))==0)
sl@0
   916
		{
sl@0
   917
		iAccess=RDbRowSet::EInsertOnly;
sl@0
   918
		iScript.WriteLine(_L("Access is insert only"));
sl@0
   919
		}
sl@0
   920
	else
sl@0
   921
		FatalError(_L("Expected UPDATE|INSERT|READ to follow ACCESS statement"));
sl@0
   922
	}
sl@0
   923
sl@0
   924
void TScriptEngine::DoResultsL()
sl@0
   925
	{
sl@0
   926
	// test its right function
sl@0
   927
	TScriptToken token;
sl@0
   928
	iScript.GetNextTokenFromLine(token);
sl@0
   929
	TEST2(token.CompareF(_L("RESULTS")), 0);
sl@0
   930
	//
sl@0
   931
	iScript.GetNextTokenFromLine(token);
sl@0
   932
	if (token.Compare(_L("{"))!=0)
sl@0
   933
		FatalError(_L("missing '{'"));
sl@0
   934
	iScript.GetNextTokenFromLine(token);					// first value
sl@0
   935
	TLex value;
sl@0
   936
	RDbRowSet& rowset=iResults.iView;
sl@0
   937
	CDbColSet* colset=rowset.ColSetL();
sl@0
   938
	CleanupStack::PushL(colset);
sl@0
   939
	TDbColNo colno=colset->ColNo(KRowIdColName);
sl@0
   940
	CArrayFixFlat<TInt>* rowIdScript=new CArrayFixFlat<TInt>(4);
sl@0
   941
	CleanupStack::PushL(rowIdScript);
sl@0
   942
	CArrayFixFlat<TInt>* rowIdView=new CArrayFixFlat<TInt>(4);
sl@0
   943
	CleanupStack::PushL(rowIdView);
sl@0
   944
	rowset.BeginningL();
sl@0
   945
	while (rowset.NextL())
sl@0
   946
		{
sl@0
   947
		rowset.GetL();
sl@0
   948
		TUint rIdScript;
sl@0
   949
		value=token;
sl@0
   950
		if (value.Val(rIdScript)!=KErrNone)
sl@0
   951
			{
sl@0
   952
			TScriptLine line;
sl@0
   953
			line.Format(_L("Unable to extract row id from \"%S\""),&token);
sl@0
   954
			FatalError(line);
sl@0
   955
			}
sl@0
   956
		TUint rIdView=rowset.ColUint(colno);
sl@0
   957
		rowIdScript->AppendL(rIdScript);
sl@0
   958
		rowIdView->AppendL(rIdView);
sl@0
   959
		iScript.GetNextTokenFromLine(token);
sl@0
   960
		if (token.Compare(_L(","))==0 || token.Compare(_L("}"))==0)
sl@0
   961
			{
sl@0
   962
			if (rowIdScript->Count())
sl@0
   963
				{
sl@0
   964
				TKeyArrayFix key(0,ECmpTInt);
sl@0
   965
				rowIdScript->Sort(key);
sl@0
   966
				rowIdView->Sort(key);
sl@0
   967
				for (TInt ii=0;ii<rowIdScript->Count();++ii)
sl@0
   968
					{
sl@0
   969
					TInt expectedId=(*rowIdScript)[ii];
sl@0
   970
					TInt actualId=(*rowIdView)[ii];
sl@0
   971
					if (actualId!=expectedId)
sl@0
   972
						{
sl@0
   973
						TScriptLine line;
sl@0
   974
						line.Format(_L("expected row id %d, actual row id %d"),actualId,expectedId);
sl@0
   975
						FatalError(line);
sl@0
   976
						}
sl@0
   977
					}
sl@0
   978
				rowIdScript->Reset();
sl@0
   979
				rowIdView->Reset();
sl@0
   980
				}
sl@0
   981
			if (token.Compare(_L(","))==0)
sl@0
   982
				iScript.GetNextTokenFromLine(token);
sl@0
   983
			}
sl@0
   984
		}
sl@0
   985
	if (token.Compare(_L("}"))!=0)
sl@0
   986
		FatalError(_L("too many results expected"));
sl@0
   987
	CleanupStack::PopAndDestroy(3);	// arrays + colset
sl@0
   988
	iScript.ConsumeStatement();
sl@0
   989
	}
sl@0
   990
sl@0
   991
//
sl@0
   992
// same as Sql create statement, but adds a counter
sl@0
   993
//
sl@0
   994
void TScriptEngine::DoBuildTable()
sl@0
   995
	{
sl@0
   996
	// test its right function
sl@0
   997
	TScriptToken keyword;
sl@0
   998
	iScript.GetNextTokenFromStatement(keyword);
sl@0
   999
	TEST2(keyword.CompareF(_L("BUILD")), 0);
sl@0
  1000
	//
sl@0
  1001
	TScriptLine sql(_L("CREATE "));
sl@0
  1002
	sql.Append(iScript.Statement());
sl@0
  1003
	TInt pos=sql.Find(_L("("));
sl@0
  1004
	sql.Insert(++pos,_L("Rw COUNTER,"));
sl@0
  1005
	iScript.ConsumeStatement();
sl@0
  1006
	ExecuteSql(sql);
sl@0
  1007
	}
sl@0
  1008
sl@0
  1009
//
sl@0
  1010
// same as Sql select statement, but makes sure counter is included
sl@0
  1011
//
sl@0
  1012
void TScriptEngine::DoQuery()
sl@0
  1013
	{
sl@0
  1014
	// test its right function
sl@0
  1015
	TScriptToken keyword;
sl@0
  1016
	iScript.GetNextTokenFromStatement(keyword);
sl@0
  1017
	TEST2(keyword.CompareF(_L("QUERY")), 0);
sl@0
  1018
	//
sl@0
  1019
	TScriptLine sql(iScript.Statement());
sl@0
  1020
	if (sql.Find(_L("*"))!=0)
sl@0
  1021
		{
sl@0
  1022
		sql.Insert(0,_L(","));
sl@0
  1023
		sql.Insert(0,KRowIdColName);
sl@0
  1024
		}
sl@0
  1025
	sql.Insert(0,_L("SELECT "));
sl@0
  1026
	iScript.ConsumeStatement();
sl@0
  1027
	ExecuteSql(sql);
sl@0
  1028
	}
sl@0
  1029
sl@0
  1030
void TScriptEngine::FatalError(const TDesC& aLine)
sl@0
  1031
	{
sl@0
  1032
	iScript.WriteError(aLine);
sl@0
  1033
	TEST(0);
sl@0
  1034
	}
sl@0
  1035
sl@0
  1036
void TScriptEngine::FatalError()
sl@0
  1037
	{
sl@0
  1038
	FatalError(_L("wrong expected value"));
sl@0
  1039
	}
sl@0
  1040
sl@0
  1041
void TScriptEngine::FatalSqlError(const TDesC& aLine)
sl@0
  1042
	{
sl@0
  1043
	iScript.WriteSqlError(iResults,aLine);
sl@0
  1044
	TEST(0);
sl@0
  1045
	}
sl@0
  1046
sl@0
  1047
void TScriptEngine::DoPopulate()
sl@0
  1048
	{
sl@0
  1049
	// check its right function
sl@0
  1050
	TScriptToken token;
sl@0
  1051
	iScript.GetNextTokenFromLine(token);
sl@0
  1052
	TEST2(token.CompareF(_L("POPULATE")), 0);
sl@0
  1053
	//
sl@0
  1054
	TScriptLine sqlbase=_L("INSERT INTO ");
sl@0
  1055
	iScript.GetNextTokenFromLine(token);	// table name
sl@0
  1056
	sqlbase.AppendFormat(_L("%S "),&token);
sl@0
  1057
	iScript.GetNextTokenFromLine(token);
sl@0
  1058
	if (token.Compare(_L("("))==0)			// optional column names present?
sl@0
  1059
		{
sl@0
  1060
		for (;;)
sl@0
  1061
			{
sl@0
  1062
			sqlbase.AppendFormat(token);
sl@0
  1063
			if (token.Compare(_L(")"))==0)
sl@0
  1064
				break;
sl@0
  1065
			iScript.GetNextTokenFromLine(token);
sl@0
  1066
			}
sl@0
  1067
		iScript.GetNextTokenFromLine(token);
sl@0
  1068
		}
sl@0
  1069
	if (token.Compare(_L("{"))!=0)
sl@0
  1070
		FatalError(_L("missing '{'"));
sl@0
  1071
	sqlbase.AppendFormat(_L(" VALUES ("));
sl@0
  1072
	iScript.GetNextTokenFromLine(token);	// first value
sl@0
  1073
	TheDatabase.Begin();					// all in same transaction
sl@0
  1074
	for (;;)
sl@0
  1075
		{
sl@0
  1076
		if (token.Compare(_L("}"))==0)
sl@0
  1077
			break;
sl@0
  1078
		TScriptLine sql=sqlbase;
sl@0
  1079
		for (;;)
sl@0
  1080
			{
sl@0
  1081
			sql.Append(token);
sl@0
  1082
			iScript.GetNextTokenFromLine(token);
sl@0
  1083
			if (token.Compare(_L(","))==0)
sl@0
  1084
				{
sl@0
  1085
				sql.Append(token);			// comma
sl@0
  1086
				iScript.GetNextTokenFromLine(token);
sl@0
  1087
				}
sl@0
  1088
			else
sl@0
  1089
				break;
sl@0
  1090
			}
sl@0
  1091
		sql.AppendFormat(_L(")"));
sl@0
  1092
		ExecuteSql(sql);
sl@0
  1093
		TestForNoError();
sl@0
  1094
		}
sl@0
  1095
	TheDatabase.Commit();
sl@0
  1096
	iScript.ConsumeStatement();
sl@0
  1097
	}
sl@0
  1098
sl@0
  1099
void TScriptEngine::DoPrintL()
sl@0
  1100
	{
sl@0
  1101
	// check its right function
sl@0
  1102
	TScriptToken keyword;
sl@0
  1103
	iScript.GetNextTokenFromStatement(keyword);
sl@0
  1104
	TEST2(keyword.CompareF(_L("PRINT")), 0);
sl@0
  1105
	//
sl@0
  1106
	iScript.GetNextTokenFromStatement(keyword);
sl@0
  1107
	if (keyword.CompareF(_L("VIEW"))==0)
sl@0
  1108
		PrintL(iResults.iView);
sl@0
  1109
	else if (keyword.CompareF(_L("TABLE"))==0)
sl@0
  1110
		{
sl@0
  1111
		iScript.GetNextTokenFromStatement(keyword);	// name of table
sl@0
  1112
		RDbTable table;
sl@0
  1113
		TInt err=table.Open(TheDatabase,keyword,table.EReadOnly);
sl@0
  1114
		if (err!=KErrNone)
sl@0
  1115
			FatalError(_L("unable to open table"));
sl@0
  1116
		PrintL(table);
sl@0
  1117
		table.Close();
sl@0
  1118
		}
sl@0
  1119
	else
sl@0
  1120
		FatalError(_L("expected VIEW or TABLE keyword not present"));
sl@0
  1121
	}
sl@0
  1122
sl@0
  1123
void TScriptEngine::DoCompareL()
sl@0
  1124
	{
sl@0
  1125
	// check its right function
sl@0
  1126
	TScriptToken keyword;
sl@0
  1127
	iScript.GetNextTokenFromLine(keyword);
sl@0
  1128
	TEST2(keyword.CompareF(_L("COMPARE")), 0);
sl@0
  1129
	//
sl@0
  1130
	iScript.GetNextTokenFromLine(keyword);
sl@0
  1131
	if (keyword.CompareF(_L("VIEW"))==0)
sl@0
  1132
		CompareL(iResults.iView);
sl@0
  1133
	else if (keyword.CompareF(_L("TABLE"))==0)
sl@0
  1134
		{
sl@0
  1135
		iScript.GetNextTokenFromLine(keyword);	// name of table
sl@0
  1136
		RDbTable table;
sl@0
  1137
		TInt err=table.Open(TheDatabase,keyword,table.EReadOnly);
sl@0
  1138
		if (err!=KErrNone)
sl@0
  1139
			FatalError(_L("unable to open table"));
sl@0
  1140
		CompareL(table);
sl@0
  1141
		table.Close();
sl@0
  1142
		}
sl@0
  1143
	else
sl@0
  1144
		FatalError(_L("expected VIEW or TABLE keyword not present"));
sl@0
  1145
	}
sl@0
  1146
sl@0
  1147
void TScriptEngine::CompareL(RDbRowSet& aRowSet)
sl@0
  1148
	{
sl@0
  1149
	TScriptToken token;
sl@0
  1150
	iScript.GetNextTokenFromLine(token);
sl@0
  1151
	TBool rowIdMode=EFalse;
sl@0
  1152
	CArrayFixFlat<TInt>* rowIdToTest=new CArrayFixFlat<TInt>(4);
sl@0
  1153
	CleanupStack::PushL(rowIdToTest);
sl@0
  1154
	if (token.Compare(_L("("))==0)				// optional row ids present?
sl@0
  1155
		{
sl@0
  1156
		rowIdMode=ETrue;
sl@0
  1157
		iScript.GetNextTokenFromLine(token);	// first value
sl@0
  1158
		TLex value;
sl@0
  1159
		TInt rowId;
sl@0
  1160
		for (;;)
sl@0
  1161
			{
sl@0
  1162
			value=token;
sl@0
  1163
			TEST2(value.Val(rowId), KErrNone);
sl@0
  1164
			rowIdToTest->AppendL(rowId);		// add row id to array
sl@0
  1165
			iScript.GetNextTokenFromLine(token);
sl@0
  1166
			if (token.Compare(_L(")"))==0)
sl@0
  1167
				break;
sl@0
  1168
			if (token.Compare(_L(","))==0)
sl@0
  1169
				iScript.GetNextTokenFromLine(token);
sl@0
  1170
			}
sl@0
  1171
		iScript.GetNextTokenFromLine(token);
sl@0
  1172
		}
sl@0
  1173
	if (token.Compare(_L("{"))!=0)
sl@0
  1174
		FatalError(_L("missing '{'"));
sl@0
  1175
	TInt columns=aRowSet.ColCount();
sl@0
  1176
	CDbColSet* colset=aRowSet.ColSetL();
sl@0
  1177
	aRowSet.BeginningL();
sl@0
  1178
	while (aRowSet.NextL())
sl@0
  1179
		{
sl@0
  1180
		aRowSet.GetL();
sl@0
  1181
		if (rowIdMode)
sl@0
  1182
			{
sl@0
  1183
			TInt currentId=aRowSet.ColUint(colset->ColNo(KRowIdColName));
sl@0
  1184
			TBool toTest=EFalse;
sl@0
  1185
			for (TInt jj=0; jj<rowIdToTest->Count(); ++jj)
sl@0
  1186
				{
sl@0
  1187
				if (currentId==(*rowIdToTest)[jj])
sl@0
  1188
					toTest=ETrue;
sl@0
  1189
				}
sl@0
  1190
			if (!toTest)
sl@0
  1191
				continue;
sl@0
  1192
			}
sl@0
  1193
		for (TInt ii=1;ii<=columns;++ii)
sl@0
  1194
			{
sl@0
  1195
			if (rowIdMode && ii==colset->ColNo(KRowIdColName))	// ignore row id column
sl@0
  1196
				continue;
sl@0
  1197
			const TDbCol& col=(*colset)[ii];
sl@0
  1198
			iScript.GetNextTokenFromLine(token);				// value
sl@0
  1199
			if (token.Compare(_L(","))==0)
sl@0
  1200
				iScript.GetNextTokenFromLine(token);			// ignore comma
sl@0
  1201
			if (aRowSet.IsColNull(ii))
sl@0
  1202
				{
sl@0
  1203
				if (token.CompareF(_L("NULL"))!=0)
sl@0
  1204
					FatalError(_L("NULL expected"));
sl@0
  1205
				continue;
sl@0
  1206
				}
sl@0
  1207
			CompareValues(aRowSet,ii,col.iType,token);
sl@0
  1208
			}
sl@0
  1209
		}
sl@0
  1210
	delete colset;
sl@0
  1211
	CleanupStack::PopAndDestroy();				// rowIdToTest
sl@0
  1212
	iScript.GetNextTokenFromLine(token);		// look for closing '}'
sl@0
  1213
	if (token.Compare(_L("}"))!=0)
sl@0
  1214
		FatalError(_L("missing '}'"));
sl@0
  1215
	iScript.ConsumeStatement();
sl@0
  1216
	}
sl@0
  1217
sl@0
  1218
//
sl@0
  1219
// compares the value from a rowset aRowset, colimn number aColNo and of type aType, with the value
sl@0
  1220
// contained in the descriptor aToken
sl@0
  1221
//
sl@0
  1222
void TScriptEngine::CompareValues(RDbRowSet& aRowSet,TDbColNo ColNo,TDbColType aType,const TDesC& aToken)
sl@0
  1223
	{
sl@0
  1224
	TLex value=aToken;
sl@0
  1225
	switch (aType)
sl@0
  1226
		{
sl@0
  1227
	case EDbColInt32:
sl@0
  1228
		{
sl@0
  1229
		TInt num;
sl@0
  1230
		TEST2(value.Val(num), KErrNone);
sl@0
  1231
		if (num!=aRowSet.ColInt(ColNo))
sl@0
  1232
			FatalError();
sl@0
  1233
		break;
sl@0
  1234
		}
sl@0
  1235
	case EDbColInt8:
sl@0
  1236
		{
sl@0
  1237
		TInt8 num8;
sl@0
  1238
		TEST2(value.Val(num8), KErrNone);
sl@0
  1239
		if (num8!=aRowSet.ColInt8(ColNo))
sl@0
  1240
			FatalError();
sl@0
  1241
		break;
sl@0
  1242
		}
sl@0
  1243
	case EDbColInt16:
sl@0
  1244
		{
sl@0
  1245
		TInt16 num16;
sl@0
  1246
		TEST2(value.Val(num16), KErrNone);
sl@0
  1247
		if (num16!=aRowSet.ColInt16(ColNo))
sl@0
  1248
			FatalError();
sl@0
  1249
		break;
sl@0
  1250
		}
sl@0
  1251
	case EDbColInt64:
sl@0
  1252
		{
sl@0
  1253
		TInt64 num64;
sl@0
  1254
		TEST2(value.Val(num64), KErrNone);
sl@0
  1255
		if (num64!=aRowSet.ColInt64(ColNo))
sl@0
  1256
			FatalError();
sl@0
  1257
		break;
sl@0
  1258
		}
sl@0
  1259
	case EDbColUint8:
sl@0
  1260
		{
sl@0
  1261
		TUint8 numu8;
sl@0
  1262
		TEST2(value.Val(numu8,EDecimal), KErrNone);
sl@0
  1263
		if (numu8!=aRowSet.ColUint8(ColNo))
sl@0
  1264
			FatalError();
sl@0
  1265
		break;
sl@0
  1266
		}
sl@0
  1267
	case EDbColUint16:
sl@0
  1268
		{
sl@0
  1269
		TUint16 numu16;
sl@0
  1270
		TEST2(value.Val(numu16,EDecimal), KErrNone);
sl@0
  1271
		if (numu16!=aRowSet.ColUint16(ColNo))
sl@0
  1272
			FatalError();
sl@0
  1273
		break;
sl@0
  1274
		}
sl@0
  1275
	case EDbColUint32:
sl@0
  1276
		{
sl@0
  1277
		TUint32 numu32;
sl@0
  1278
		TEST2(value.Val(numu32,EDecimal), KErrNone);
sl@0
  1279
		if (numu32!=aRowSet.ColUint32(ColNo))
sl@0
  1280
			FatalError();
sl@0
  1281
		break;
sl@0
  1282
		}
sl@0
  1283
	case EDbColReal32:
sl@0
  1284
		{
sl@0
  1285
		TReal32 numr32;
sl@0
  1286
		TEST2(value.Val(numr32), KErrNone);
sl@0
  1287
		if (numr32!=aRowSet.ColReal32(ColNo))
sl@0
  1288
			FatalError();
sl@0
  1289
		break;
sl@0
  1290
		}
sl@0
  1291
	case EDbColReal64:
sl@0
  1292
		{
sl@0
  1293
		TReal64 numr64;
sl@0
  1294
		TEST2(value.Val(numr64), KErrNone);
sl@0
  1295
		if (numr64!=aRowSet.ColReal64(ColNo))
sl@0
  1296
			FatalError();
sl@0
  1297
		break;
sl@0
  1298
		}
sl@0
  1299
	case EDbColText8:
sl@0
  1300
	case EDbColText16:
sl@0
  1301
		{
sl@0
  1302
		TPtrC text=aToken.Mid(1,aToken.Length()-2);			// skip quotes
sl@0
  1303
		if (text.CompareF(aRowSet.ColDes(ColNo))!=0)
sl@0
  1304
			FatalError();
sl@0
  1305
		break;
sl@0
  1306
		}
sl@0
  1307
	case EDbColDateTime:
sl@0
  1308
		{
sl@0
  1309
		TScriptLine time=aToken.Mid(1,aToken.Length()-2);	// skip hashes
sl@0
  1310
		TTime t1;
sl@0
  1311
		t1.Parse(time);
sl@0
  1312
		TTime t2(aRowSet.ColTime(ColNo).DateTime());
sl@0
  1313
		if (t1!=t2)
sl@0
  1314
			FatalError();
sl@0
  1315
		break;
sl@0
  1316
		}
sl@0
  1317
	default:
sl@0
  1318
		break;
sl@0
  1319
		}
sl@0
  1320
	}
sl@0
  1321
sl@0
  1322
void TScriptEngine::PrintL(RDbRowSet& aRowSet)
sl@0
  1323
	{
sl@0
  1324
	iScript.WriteLine(TPtrC());
sl@0
  1325
	TInt columns=aRowSet.ColCount();
sl@0
  1326
	CDbColSet* colset=aRowSet.ColSetL();
sl@0
  1327
	TScriptLine line;
sl@0
  1328
	for (TInt i=1;i<=columns;++i)
sl@0
  1329
		{
sl@0
  1330
		const TDbCol& col=(*colset)[i];
sl@0
  1331
		line.AppendFormat(_L("%S\t"),&col.iName);
sl@0
  1332
		}
sl@0
  1333
	iScript.WriteLine(line);
sl@0
  1334
	aRowSet.BeginningL();
sl@0
  1335
	while (aRowSet.NextL())
sl@0
  1336
		{
sl@0
  1337
		line=TPtrC();
sl@0
  1338
		for (TInt ii=1;ii<=columns;++ii)
sl@0
  1339
			{
sl@0
  1340
			const TDbCol& col=(*colset)[ii];
sl@0
  1341
			aRowSet.GetL();
sl@0
  1342
			if (aRowSet.IsColNull(ii))
sl@0
  1343
				{
sl@0
  1344
				line.AppendFormat(_L("NULL\t"));
sl@0
  1345
				continue;
sl@0
  1346
				}
sl@0
  1347
			switch (col.iType)
sl@0
  1348
				{
sl@0
  1349
			case EDbColInt32:
sl@0
  1350
				line.AppendFormat(_L("%d\t"),aRowSet.ColInt(ii));
sl@0
  1351
				break;
sl@0
  1352
			case EDbColInt8:
sl@0
  1353
				line.AppendFormat(_L("%d\t"),aRowSet.ColInt8(ii));
sl@0
  1354
				break;
sl@0
  1355
			case EDbColInt16:
sl@0
  1356
				line.AppendFormat(_L("%d\t"),aRowSet.ColInt16(ii));
sl@0
  1357
				break;
sl@0
  1358
			case EDbColInt64:
sl@0
  1359
				line.AppendFormat(_L("%ld\t"),aRowSet.ColInt64(ii));
sl@0
  1360
				break;
sl@0
  1361
			case EDbColUint8:
sl@0
  1362
				line.AppendFormat(_L("%u\t"),aRowSet.ColUint8(ii));
sl@0
  1363
				break;
sl@0
  1364
			case EDbColUint16:
sl@0
  1365
				line.AppendFormat(_L("%u\t"),aRowSet.ColUint16(ii));
sl@0
  1366
				break;
sl@0
  1367
			case EDbColUint32:
sl@0
  1368
				line.AppendFormat(_L("%u\t"),aRowSet.ColUint(ii));
sl@0
  1369
				break;
sl@0
  1370
			case EDbColReal32:
sl@0
  1371
				line.AppendFormat(_L("%f\t"),aRowSet.ColReal32(ii));
sl@0
  1372
				break;
sl@0
  1373
			case EDbColReal64:
sl@0
  1374
				line.AppendFormat(_L("%f\t"),aRowSet.ColReal64(ii));
sl@0
  1375
				break;
sl@0
  1376
			case EDbColText:
sl@0
  1377
				line.Append(aRowSet.ColDes(ii));
sl@0
  1378
				line.Append('\t');
sl@0
  1379
				break;
sl@0
  1380
			case EDbColDateTime:
sl@0
  1381
				{
sl@0
  1382
				TDateTime time(aRowSet.ColTime(ii).DateTime());
sl@0
  1383
				line.AppendFormat(_L("%d:%d:%d %d/%d/%d"),time.Hour(),time.Minute(),time.Second(),time.Day(),time.Month(),time.Year());
sl@0
  1384
				}
sl@0
  1385
				break;
sl@0
  1386
			case EDbColLongText:
sl@0
  1387
				{
sl@0
  1388
				RDbColReadStream blob;
sl@0
  1389
				blob.OpenLC(aRowSet,ii);
sl@0
  1390
				TScriptLine text;
sl@0
  1391
				blob.ReadL(text,aRowSet.ColLength(ii));
sl@0
  1392
				CleanupStack::PopAndDestroy();
sl@0
  1393
				line.AppendFormat(_L("%S\t"),&text);
sl@0
  1394
				}
sl@0
  1395
			default:
sl@0
  1396
				break;
sl@0
  1397
				}
sl@0
  1398
			}
sl@0
  1399
		iScript.WriteLine(line);
sl@0
  1400
		}
sl@0
  1401
	iScript.WriteLine(TPtrC());
sl@0
  1402
	delete colset;
sl@0
  1403
	}
sl@0
  1404
sl@0
  1405
sl@0
  1406
//
sl@0
  1407
// Create the database
sl@0
  1408
//
sl@0
  1409
LOCAL_C void CreateDatabase()
sl@0
  1410
	{
sl@0
  1411
	TEST2(TheDatabase.Replace(TheFs,KTestDatabase), KErrNone);
sl@0
  1412
	}
sl@0
  1413
sl@0
  1414
//
sl@0
  1415
// Close the database
sl@0
  1416
//
sl@0
  1417
LOCAL_C void CloseDatabase()
sl@0
  1418
	{
sl@0
  1419
	TheDatabase.Close();
sl@0
  1420
	}
sl@0
  1421
sl@0
  1422
//
sl@0
  1423
// Prepare the test directory.
sl@0
  1424
//
sl@0
  1425
LOCAL_C void SetupTestDirectory()
sl@0
  1426
    {
sl@0
  1427
	TInt err=TheFs.Connect();
sl@0
  1428
	TEST2(err, KErrNone);
sl@0
  1429
//
sl@0
  1430
	err=TheFs.MkDir(KTestDatabase);
sl@0
  1431
	TEST(err==KErrNone || err==KErrAlreadyExists);
sl@0
  1432
	}
sl@0
  1433
sl@0
  1434
//
sl@0
  1435
// Initialise the cleanup stack.
sl@0
  1436
//
sl@0
  1437
LOCAL_C void SetupCleanup()
sl@0
  1438
    {
sl@0
  1439
	TheTrapCleanup=CTrapCleanup::New();
sl@0
  1440
	TEST(TheTrapCleanup!=NULL);
sl@0
  1441
	TRAPD(err,\
sl@0
  1442
		{\
sl@0
  1443
		for (TInt i=KTestCleanupStack;i>0;i--)\
sl@0
  1444
			CleanupStack::PushL((TAny*)0);\
sl@0
  1445
		CleanupStack::Pop(KTestCleanupStack);\
sl@0
  1446
		});
sl@0
  1447
	TEST2(err, KErrNone);
sl@0
  1448
	}
sl@0
  1449
sl@0
  1450
/**
sl@0
  1451
@SYMTestCaseID          SYSLIB-DBMS-CT-0632
sl@0
  1452
@SYMTestCaseDesc        Executes the script files
sl@0
  1453
@SYMTestPriority        Medium
sl@0
  1454
@SYMTestActions         Start the script engine
sl@0
  1455
@SYMTestExpectedResults Test must not fail
sl@0
  1456
@SYMREQ                 REQ0000
sl@0
  1457
*/
sl@0
  1458
LOCAL_C void RunScriptL()
sl@0
  1459
	{
sl@0
  1460
	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0632 Running script "));
sl@0
  1461
	CreateDatabase();
sl@0
  1462
	TScriptEngine script;
sl@0
  1463
	script.RunL();
sl@0
  1464
	CloseDatabase();
sl@0
  1465
	TheView.Close();
sl@0
  1466
	}
sl@0
  1467
sl@0
  1468
//
sl@0
  1469
// entry point
sl@0
  1470
//
sl@0
  1471
GLDEF_C TInt E32Main()
sl@0
  1472
    {
sl@0
  1473
	TheTest.Title();
sl@0
  1474
	SetupTestDirectory();
sl@0
  1475
	SetupCleanup();
sl@0
  1476
	__UHEAP_MARK;
sl@0
  1477
//
sl@0
  1478
	TRAPD(err,RunScriptL());
sl@0
  1479
	TEST2(err, KErrNone);
sl@0
  1480
sl@0
  1481
	//deletion of data files must be done before call to end - DEF047652
sl@0
  1482
	::DeleteDataFile(KTestDatabase);
sl@0
  1483
	::DeleteDataFile(KOutputFile);//Comment this line if you want to keep "t_script.log" file.
sl@0
  1484
	TheTest.End();
sl@0
  1485
//
sl@0
  1486
	__UHEAP_MARKEND;
sl@0
  1487
	delete TheTrapCleanup;
sl@0
  1488
sl@0
  1489
	TheFs.Close();
sl@0
  1490
	TheTest.Close();
sl@0
  1491
sl@0
  1492
	return 0;
sl@0
  1493
    }