diff -r 000000000000 -r 08ec8eefde2f persistentstorage/dbms/tdbms/t_dbscript.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/dbms/tdbms/t_dbscript.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,1493 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include +#include + +LOCAL_D RTest TheTest(_L("t_dbscript")); +LOCAL_D CTrapCleanup* TheTrapCleanup; +LOCAL_D RDbNamedDatabase TheDatabase; +LOCAL_D RFs TheFs; +LOCAL_D RDbView TheView; +// +const TPtrC KTestDatabase=_L("c:\\dbms-tst\\t_script.db"); + +const TPtrC KRomScriptFile=_L("z:\\test\\t_script.txt"); + +const TPtrC KOutputFile=_L("c:\\dbms-tst\\t_script.log"); + +const TInt KTestCleanupStack=0x20; +const TPtrC KDDLKeywords[]={_L("CREATE"),_L("DROP"),_L("ALTER")}; +const TPtrC KDMLKeywords[]={_L("INSERT"),_L("DELETE"),_L("UPDATE")}; +const TPtrC KQueryKeywords[]={_L("SELECT")}; +const TPtrC KScriptKeywords[]={_L("PRINT"),_L("ROWS"),_L("COMPARE"),_L("ERROR"),_L("!"), + _L("POPULATE"),_L("RESULTS"),_L("BUILD"),_L("QUERY"), + _L("NORMAL"),_L("FOLDED"),_L("COLLATED"),_L("START"),_L("STOP"), + _L("LOAD"),_L("ECHO"),_L("WINDOW"),_L("ACCESS")}; +const TPtrC KRowIdColName=_L("Rw"); +enum TKeyword {EPrint,ERows,ECompare,EError,EComment,EPopulate,EResults,EBuild,EQuery,ENormal, + EFolded,ECollated,EStart,EStop,ELoad,EEcho,EWindow,EAccess,ENumKeywords,EUnknown}; +// +typedef TBuf<256> TScriptLine; +typedef TBuf<256> TScriptToken; +// +#define ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0])) + +class TScript; +class TTimer + { +public: + inline TTimer(TScript& aScript); + void Start(const TDesC& aDes); + void Stop(const TDesC& aDes); +private: + TUint iTicks; + TScript& iScript; + }; + +class TResults + { +public: + inline TResults(); +public: + RDbView& iView; + TInt iError; + TInt iRows; + TInt iLineNo; + TScriptLine iLine; + }; + +class TSqlStatement + { +private: + enum TSqlType {EDML,EDDL,EQuery,EUnknown}; +public: + inline TSqlStatement(const TDesC& aSql,TResults& aResults); + TInt Execute(TDbTextComparison aTextComparison=EDbCompareNormal, + RDbRowSet::TAccess aAccess=RDbRowSet::EReadOnly,TBool aWindow=EFalse) const; +private: + void ExecuteSql(TDbTextComparison aTextComparison) const; + void ExecuteQuery(RDbRowSet::TAccess aAccess,TBool aWindow) const; + TSqlType SqlType() const; +private: + const TDesC& iSql; + TResults& iResults; + }; + +class TScript + { +public: + TScript(); + ~TScript() + { + iFile.Close(); + } + TInt ReadNextStatement(); + void GetNextTokenFromStatement(TDes& aToken); + void GetNextTokenFromLine(TDes& aToken); + TPtrC Statement(); + TInt IntValue(); + void WriteLine(const TDesC& aLine); + void WriteError(const TDesC& aLine); + void WriteSqlError(const TResults& aResults,const TDesC& aLine); + void WriteComment(const TDesC& aLine); + TKeyword Keyword(const TDesC& aKeyword) const; + void ConsumeLine(); + void ConsumeStatement(); + inline TInt LineNo() const; +private: + TInt ReadNextLine(); + TInt AppendNextLine(); + TBool IsStatement(); +private: + TFileText iInput; + TFileText iOutput; + TScriptLine iBuf; + TLex iStatement; + TLex iLine; + TInt iLineNo; + RFile iFile; + }; + +class TScriptEngine + { +public: + inline TScriptEngine(); + void RunL(); +private: + void ExecuteL(); + TInt ExecuteScriptL(); + TInt ExecuteSql(const TDesC& aSql); + TInt ExecuteSql(); + // keyword operations + void DoPrintL(); + void DoComment(); + void DoError(); + void DoEcho(); + void DoWindow(); + void DoAccess(); + void DoRows(); + void DoCompareL(); + void DoPopulate(); + void DoResultsL(); + void DoBuildTable(); + void DoQuery(); + void DoTextComparison(TKeyword aKeyword); + void DoStartTimer(); + void DoStopTimer(); + void DoLoadDb(); + // + void PrintL(RDbRowSet& aRowSet); + void CompareL(RDbRowSet& aRowSet); + void CompareValues(RDbRowSet& aRowSet,TDbColNo ColNo,TDbColType aType,const TDesC& aToken); + void FatalError(const TDesC& aLine); + void FatalError(); + void FatalSqlError(const TDesC& aLine); + void TestForNoError(); +private: + TScript iScript; + TResults iResults; + TDbTextComparison iTextComparison; + TTimer iTimer; + TBool iEcho; + TBool iWindow; + RDbRowSet::TAccess iAccess; + + }; + +// +// class TTimer +// + +inline TTimer::TTimer(TScript& aScript) + : iScript(aScript) + {} + +void TTimer::Start(const TDesC& aDes) + { + TScriptLine line; + line.Format(_L("%S: "),&aDes); + iScript.WriteLine(line); + iTicks=User::TickCount(); + } + +void TTimer::Stop(const TDesC& aDes) + { + TScriptLine line; + line.Format(_L("%S: "),&aDes); +#ifdef __EPOC32__ +#define TICK_TIME 15625 +#else +#define TICK_TIME 100000 +#endif + TInt microSec=(User::TickCount()-iTicks)*TICK_TIME; + TUint sec=microSec/1000000; + TUint centi=(microSec/10000)-sec*100; + line.AppendFormat(_L("%u.%02us\n"),sec,centi); + iScript.WriteLine(line); + } + +/////////////////////////////////////////////////////////////////////////////////////// + +LOCAL_C void DeleteDataFile(const TDesC& aFullName) + { + RFs fsSession; + TInt err = fsSession.Connect(); + if(err == KErrNone) + { + TEntry entry; + if(fsSession.Entry(aFullName, entry) == KErrNone) + { + RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); + if(err != KErrNone) + { + RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); + } + err = fsSession.Delete(aFullName); + if(err != KErrNone) + { + RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); + } + } + fsSession.Close(); + } + else + { + RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); + } + } + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +//Tests macros and functions. +//If (!aValue) then the test will be panicked, the test data files will be deleted. +static void Check(TInt aValue, TInt aLine) + { + if(!aValue) + { + RDebug::Print(_L("*** Expression evaluated to false\r\n")); + DeleteDataFile(KTestDatabase); + DeleteDataFile(KOutputFile); + TheTest(EFalse, aLine); + } + } +//If (aValue != aExpected) then the test will be panicked, the test data files will be deleted. +static void Check(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); + DeleteDataFile(KTestDatabase); + DeleteDataFile(KOutputFile); + TheTest(EFalse, aLine); + } + } +//Use these to test conditions. +#define TEST(arg) Check((arg), __LINE__) +#define TEST2(aValue, aExpected) Check(aValue, aExpected, __LINE__) + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// + +// +// class TResults +// + +inline TResults::TResults() + : iView(TheView),iError(KErrNone) + {} + + +// +// class TSqlStatement +// + +inline TSqlStatement::TSqlStatement(const TDesC& aSql,TResults& aResults) + : iSql(aSql),iResults(aResults) + {} + +// +// executes DML or DDL +// +void TSqlStatement::ExecuteSql(TDbTextComparison aTextComparison) const + { + TInt r=TheDatabase.Execute(iSql,aTextComparison); + if (r<0) + iResults.iError=r; + else + { + iResults.iError=KErrNone; + iResults.iRows=r; + } + } + +void TSqlStatement::ExecuteQuery(RDbRowSet::TAccess aAccess,TBool aWindow) const + { + iResults.iView.Close(); // discard any previous queries + TInt& err=iResults.iError; + if (aWindow) + err=iResults.iView.Prepare(TheDatabase,iSql,KDbUnlimitedWindow,aAccess); + else + err=iResults.iView.Prepare(TheDatabase,iSql,aAccess); + if (err==KErrNone) + err=iResults.iView.EvaluateAll(); + } + +// +// determines the type of sql statement by matching keywords +// +TSqlStatement::TSqlType TSqlStatement::SqlType() const + { + for (TUint i=0;i0 && iBuf[0]==0xfeff) // unicode stream marker + iBuf.Delete(0,1); + iLineNo++; + iLine=iBuf; + iLine.SkipSpaceAndMark(); + } + return KErrNone; + } + +// +// adds next line from file to iLine +// +TInt TScript::AppendNextLine() + { + TScriptLine line; + do { + TInt r=iInput.Read(line); + if (r!=KErrNone) + return r; + iLineNo++; + } while (line.Length()==0); + iBuf=iLine.MarkedToken(); + iBuf.Append(line); + iLine=iBuf; + return KErrNone; + } + +void TScript::WriteError(const TDesC& aLine) + { + TScriptLine line; + line.Format(_L("Error at line %d: %S\n"),iLineNo,&aLine); + WriteLine(line); + TheTest.Printf(line); + } + +void TScript::WriteSqlError(const TResults& aResults,const TDesC& aLine) + { + TScriptLine line; + line.Format(_L("Error at line %d: %S :-\n"),aResults.iLineNo,&aLine); + WriteLine(line); + TheTest.Printf(line); + line.Format(_L("\t%S\n"),&aResults.iLine); + WriteLine(line); + TheTest.Printf(line); + } + +void TScript::WriteLine(const TDesC& aLine) + { + TScriptLine l=aLine; + l.Append('\r'); + iOutput.Write(l); + } + +void TScript::WriteComment(const TDesC& aLine) + { + TScriptLine line; + line.Format(_L("\n%S"),&aLine); + WriteLine(line); + } + +// +// returns the integer n from the ' = n ' which must follow in the statement +// +TInt TScript::IntValue() + { + TScriptToken keyword; + GetNextTokenFromStatement(keyword); + if (keyword.Compare(_L("="))!=0) + WriteError(_L("expected '=' missing")); + iStatement.SkipSpaceAndMark(); + TInt num=0; + TInt err=iStatement.Val(num); + if (err!=KErrNone) + WriteError(_L("expected number missing")); + return num; + } + +TKeyword TScript::Keyword(const TDesC& aKeyword) const + { + for (TInt ii=0; ii=0) + FatalSqlError(_L("no error when one was expected")); + line=_L("\t\tERROR OK"); + } + else + { + TInt err=iScript.IntValue(); + if (iResults.iError!=err) + { + line.Format(_L("expected error %d, actual error %d"),err,iResults.iError); + FatalSqlError(line); + } + line.Format(_L("\t\tERROR=%D OK"),err); + } + iResults.iError=0; + iScript.WriteLine(line); + } + +void TScriptEngine::DoRows() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("ROWS")), 0); + // + TScriptLine line; + TInt rows=iScript.IntValue(); + if (iResults.iRows!=rows) + { + line.Format(_L("expected rows %d, actual rows %d"),rows,iResults.iRows); + FatalSqlError(line); + } + line.Format(_L("\t\tROWS=%D OK"),rows); + iScript.WriteLine(line); + } + +void TScriptEngine::DoLoadDb() + { + // test its right function + TScriptToken token; + iScript.GetNextTokenFromStatement(token); + TEST2(token.CompareF(_L("LOAD")), 0); + // + TFileName database(iScript.Statement()); + TheDatabase.Close(); + TScriptLine line; + line.Format(_L("Opening database: %S"),&database); + iScript.WriteLine(line); + TEST2(TheDatabase.Open(TheFs,database), KErrNone); + } + +void TScriptEngine::DoEcho() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("ECHO")), 0); + // + iScript.GetNextTokenFromStatement(keyword); + if (keyword.CompareF(_L("OFF"))==0) + { + iEcho=EFalse; + iScript.WriteLine(_L("Echo is off")); + } + else if (keyword.CompareF(_L("ON"))==0) + { + iEcho=ETrue; + iScript.WriteLine(_L("Echo is on")); + } + else + FatalError(_L("Expected ON|OFF to follow ECHO statement")); + } + +void TScriptEngine::DoWindow() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("WINDOW")), 0); + // + iScript.GetNextTokenFromStatement(keyword); + if (keyword.CompareF(_L("OFF"))==0) + { + iWindow=EFalse; + iScript.WriteLine(_L("Window is off")); + } + else if (keyword.CompareF(_L("ON"))==0) + { + iWindow=ETrue; + iScript.WriteLine(_L("Window is on")); + } + else + FatalError(_L("Expected ON|OFF to follow WINDOW statement")); + } + +void TScriptEngine::DoAccess() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("ACCESS")), 0); + // + iScript.GetNextTokenFromStatement(keyword); + if (keyword.CompareF(_L("UPDATE"))==0) + { + iAccess=RDbRowSet::EUpdatable; + iScript.WriteLine(_L("Access is updateable")); + } + else if (keyword.CompareF(_L("READ"))==0) + { + iAccess=RDbRowSet::EReadOnly; + iScript.WriteLine(_L("Access is read only")); + } + else if (keyword.CompareF(_L("INSERT"))==0) + { + iAccess=RDbRowSet::EInsertOnly; + iScript.WriteLine(_L("Access is insert only")); + } + else + FatalError(_L("Expected UPDATE|INSERT|READ to follow ACCESS statement")); + } + +void TScriptEngine::DoResultsL() + { + // test its right function + TScriptToken token; + iScript.GetNextTokenFromLine(token); + TEST2(token.CompareF(_L("RESULTS")), 0); + // + iScript.GetNextTokenFromLine(token); + if (token.Compare(_L("{"))!=0) + FatalError(_L("missing '{'")); + iScript.GetNextTokenFromLine(token); // first value + TLex value; + RDbRowSet& rowset=iResults.iView; + CDbColSet* colset=rowset.ColSetL(); + CleanupStack::PushL(colset); + TDbColNo colno=colset->ColNo(KRowIdColName); + CArrayFixFlat* rowIdScript=new CArrayFixFlat(4); + CleanupStack::PushL(rowIdScript); + CArrayFixFlat* rowIdView=new CArrayFixFlat(4); + CleanupStack::PushL(rowIdView); + rowset.BeginningL(); + while (rowset.NextL()) + { + rowset.GetL(); + TUint rIdScript; + value=token; + if (value.Val(rIdScript)!=KErrNone) + { + TScriptLine line; + line.Format(_L("Unable to extract row id from \"%S\""),&token); + FatalError(line); + } + TUint rIdView=rowset.ColUint(colno); + rowIdScript->AppendL(rIdScript); + rowIdView->AppendL(rIdView); + iScript.GetNextTokenFromLine(token); + if (token.Compare(_L(","))==0 || token.Compare(_L("}"))==0) + { + if (rowIdScript->Count()) + { + TKeyArrayFix key(0,ECmpTInt); + rowIdScript->Sort(key); + rowIdView->Sort(key); + for (TInt ii=0;iiCount();++ii) + { + TInt expectedId=(*rowIdScript)[ii]; + TInt actualId=(*rowIdView)[ii]; + if (actualId!=expectedId) + { + TScriptLine line; + line.Format(_L("expected row id %d, actual row id %d"),actualId,expectedId); + FatalError(line); + } + } + rowIdScript->Reset(); + rowIdView->Reset(); + } + if (token.Compare(_L(","))==0) + iScript.GetNextTokenFromLine(token); + } + } + if (token.Compare(_L("}"))!=0) + FatalError(_L("too many results expected")); + CleanupStack::PopAndDestroy(3); // arrays + colset + iScript.ConsumeStatement(); + } + +// +// same as Sql create statement, but adds a counter +// +void TScriptEngine::DoBuildTable() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("BUILD")), 0); + // + TScriptLine sql(_L("CREATE ")); + sql.Append(iScript.Statement()); + TInt pos=sql.Find(_L("(")); + sql.Insert(++pos,_L("Rw COUNTER,")); + iScript.ConsumeStatement(); + ExecuteSql(sql); + } + +// +// same as Sql select statement, but makes sure counter is included +// +void TScriptEngine::DoQuery() + { + // test its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("QUERY")), 0); + // + TScriptLine sql(iScript.Statement()); + if (sql.Find(_L("*"))!=0) + { + sql.Insert(0,_L(",")); + sql.Insert(0,KRowIdColName); + } + sql.Insert(0,_L("SELECT ")); + iScript.ConsumeStatement(); + ExecuteSql(sql); + } + +void TScriptEngine::FatalError(const TDesC& aLine) + { + iScript.WriteError(aLine); + TEST(0); + } + +void TScriptEngine::FatalError() + { + FatalError(_L("wrong expected value")); + } + +void TScriptEngine::FatalSqlError(const TDesC& aLine) + { + iScript.WriteSqlError(iResults,aLine); + TEST(0); + } + +void TScriptEngine::DoPopulate() + { + // check its right function + TScriptToken token; + iScript.GetNextTokenFromLine(token); + TEST2(token.CompareF(_L("POPULATE")), 0); + // + TScriptLine sqlbase=_L("INSERT INTO "); + iScript.GetNextTokenFromLine(token); // table name + sqlbase.AppendFormat(_L("%S "),&token); + iScript.GetNextTokenFromLine(token); + if (token.Compare(_L("("))==0) // optional column names present? + { + for (;;) + { + sqlbase.AppendFormat(token); + if (token.Compare(_L(")"))==0) + break; + iScript.GetNextTokenFromLine(token); + } + iScript.GetNextTokenFromLine(token); + } + if (token.Compare(_L("{"))!=0) + FatalError(_L("missing '{'")); + sqlbase.AppendFormat(_L(" VALUES (")); + iScript.GetNextTokenFromLine(token); // first value + TheDatabase.Begin(); // all in same transaction + for (;;) + { + if (token.Compare(_L("}"))==0) + break; + TScriptLine sql=sqlbase; + for (;;) + { + sql.Append(token); + iScript.GetNextTokenFromLine(token); + if (token.Compare(_L(","))==0) + { + sql.Append(token); // comma + iScript.GetNextTokenFromLine(token); + } + else + break; + } + sql.AppendFormat(_L(")")); + ExecuteSql(sql); + TestForNoError(); + } + TheDatabase.Commit(); + iScript.ConsumeStatement(); + } + +void TScriptEngine::DoPrintL() + { + // check its right function + TScriptToken keyword; + iScript.GetNextTokenFromStatement(keyword); + TEST2(keyword.CompareF(_L("PRINT")), 0); + // + iScript.GetNextTokenFromStatement(keyword); + if (keyword.CompareF(_L("VIEW"))==0) + PrintL(iResults.iView); + else if (keyword.CompareF(_L("TABLE"))==0) + { + iScript.GetNextTokenFromStatement(keyword); // name of table + RDbTable table; + TInt err=table.Open(TheDatabase,keyword,table.EReadOnly); + if (err!=KErrNone) + FatalError(_L("unable to open table")); + PrintL(table); + table.Close(); + } + else + FatalError(_L("expected VIEW or TABLE keyword not present")); + } + +void TScriptEngine::DoCompareL() + { + // check its right function + TScriptToken keyword; + iScript.GetNextTokenFromLine(keyword); + TEST2(keyword.CompareF(_L("COMPARE")), 0); + // + iScript.GetNextTokenFromLine(keyword); + if (keyword.CompareF(_L("VIEW"))==0) + CompareL(iResults.iView); + else if (keyword.CompareF(_L("TABLE"))==0) + { + iScript.GetNextTokenFromLine(keyword); // name of table + RDbTable table; + TInt err=table.Open(TheDatabase,keyword,table.EReadOnly); + if (err!=KErrNone) + FatalError(_L("unable to open table")); + CompareL(table); + table.Close(); + } + else + FatalError(_L("expected VIEW or TABLE keyword not present")); + } + +void TScriptEngine::CompareL(RDbRowSet& aRowSet) + { + TScriptToken token; + iScript.GetNextTokenFromLine(token); + TBool rowIdMode=EFalse; + CArrayFixFlat* rowIdToTest=new CArrayFixFlat(4); + CleanupStack::PushL(rowIdToTest); + if (token.Compare(_L("("))==0) // optional row ids present? + { + rowIdMode=ETrue; + iScript.GetNextTokenFromLine(token); // first value + TLex value; + TInt rowId; + for (;;) + { + value=token; + TEST2(value.Val(rowId), KErrNone); + rowIdToTest->AppendL(rowId); // add row id to array + iScript.GetNextTokenFromLine(token); + if (token.Compare(_L(")"))==0) + break; + if (token.Compare(_L(","))==0) + iScript.GetNextTokenFromLine(token); + } + iScript.GetNextTokenFromLine(token); + } + if (token.Compare(_L("{"))!=0) + FatalError(_L("missing '{'")); + TInt columns=aRowSet.ColCount(); + CDbColSet* colset=aRowSet.ColSetL(); + aRowSet.BeginningL(); + while (aRowSet.NextL()) + { + aRowSet.GetL(); + if (rowIdMode) + { + TInt currentId=aRowSet.ColUint(colset->ColNo(KRowIdColName)); + TBool toTest=EFalse; + for (TInt jj=0; jjCount(); ++jj) + { + if (currentId==(*rowIdToTest)[jj]) + toTest=ETrue; + } + if (!toTest) + continue; + } + for (TInt ii=1;ii<=columns;++ii) + { + if (rowIdMode && ii==colset->ColNo(KRowIdColName)) // ignore row id column + continue; + const TDbCol& col=(*colset)[ii]; + iScript.GetNextTokenFromLine(token); // value + if (token.Compare(_L(","))==0) + iScript.GetNextTokenFromLine(token); // ignore comma + if (aRowSet.IsColNull(ii)) + { + if (token.CompareF(_L("NULL"))!=0) + FatalError(_L("NULL expected")); + continue; + } + CompareValues(aRowSet,ii,col.iType,token); + } + } + delete colset; + CleanupStack::PopAndDestroy(); // rowIdToTest + iScript.GetNextTokenFromLine(token); // look for closing '}' + if (token.Compare(_L("}"))!=0) + FatalError(_L("missing '}'")); + iScript.ConsumeStatement(); + } + +// +// compares the value from a rowset aRowset, colimn number aColNo and of type aType, with the value +// contained in the descriptor aToken +// +void TScriptEngine::CompareValues(RDbRowSet& aRowSet,TDbColNo ColNo,TDbColType aType,const TDesC& aToken) + { + TLex value=aToken; + switch (aType) + { + case EDbColInt32: + { + TInt num; + TEST2(value.Val(num), KErrNone); + if (num!=aRowSet.ColInt(ColNo)) + FatalError(); + break; + } + case EDbColInt8: + { + TInt8 num8; + TEST2(value.Val(num8), KErrNone); + if (num8!=aRowSet.ColInt8(ColNo)) + FatalError(); + break; + } + case EDbColInt16: + { + TInt16 num16; + TEST2(value.Val(num16), KErrNone); + if (num16!=aRowSet.ColInt16(ColNo)) + FatalError(); + break; + } + case EDbColInt64: + { + TInt64 num64; + TEST2(value.Val(num64), KErrNone); + if (num64!=aRowSet.ColInt64(ColNo)) + FatalError(); + break; + } + case EDbColUint8: + { + TUint8 numu8; + TEST2(value.Val(numu8,EDecimal), KErrNone); + if (numu8!=aRowSet.ColUint8(ColNo)) + FatalError(); + break; + } + case EDbColUint16: + { + TUint16 numu16; + TEST2(value.Val(numu16,EDecimal), KErrNone); + if (numu16!=aRowSet.ColUint16(ColNo)) + FatalError(); + break; + } + case EDbColUint32: + { + TUint32 numu32; + TEST2(value.Val(numu32,EDecimal), KErrNone); + if (numu32!=aRowSet.ColUint32(ColNo)) + FatalError(); + break; + } + case EDbColReal32: + { + TReal32 numr32; + TEST2(value.Val(numr32), KErrNone); + if (numr32!=aRowSet.ColReal32(ColNo)) + FatalError(); + break; + } + case EDbColReal64: + { + TReal64 numr64; + TEST2(value.Val(numr64), KErrNone); + if (numr64!=aRowSet.ColReal64(ColNo)) + FatalError(); + break; + } + case EDbColText8: + case EDbColText16: + { + TPtrC text=aToken.Mid(1,aToken.Length()-2); // skip quotes + if (text.CompareF(aRowSet.ColDes(ColNo))!=0) + FatalError(); + break; + } + case EDbColDateTime: + { + TScriptLine time=aToken.Mid(1,aToken.Length()-2); // skip hashes + TTime t1; + t1.Parse(time); + TTime t2(aRowSet.ColTime(ColNo).DateTime()); + if (t1!=t2) + FatalError(); + break; + } + default: + break; + } + } + +void TScriptEngine::PrintL(RDbRowSet& aRowSet) + { + iScript.WriteLine(TPtrC()); + TInt columns=aRowSet.ColCount(); + CDbColSet* colset=aRowSet.ColSetL(); + TScriptLine line; + for (TInt i=1;i<=columns;++i) + { + const TDbCol& col=(*colset)[i]; + line.AppendFormat(_L("%S\t"),&col.iName); + } + iScript.WriteLine(line); + aRowSet.BeginningL(); + while (aRowSet.NextL()) + { + line=TPtrC(); + for (TInt ii=1;ii<=columns;++ii) + { + const TDbCol& col=(*colset)[ii]; + aRowSet.GetL(); + if (aRowSet.IsColNull(ii)) + { + line.AppendFormat(_L("NULL\t")); + continue; + } + switch (col.iType) + { + case EDbColInt32: + line.AppendFormat(_L("%d\t"),aRowSet.ColInt(ii)); + break; + case EDbColInt8: + line.AppendFormat(_L("%d\t"),aRowSet.ColInt8(ii)); + break; + case EDbColInt16: + line.AppendFormat(_L("%d\t"),aRowSet.ColInt16(ii)); + break; + case EDbColInt64: + line.AppendFormat(_L("%ld\t"),aRowSet.ColInt64(ii)); + break; + case EDbColUint8: + line.AppendFormat(_L("%u\t"),aRowSet.ColUint8(ii)); + break; + case EDbColUint16: + line.AppendFormat(_L("%u\t"),aRowSet.ColUint16(ii)); + break; + case EDbColUint32: + line.AppendFormat(_L("%u\t"),aRowSet.ColUint(ii)); + break; + case EDbColReal32: + line.AppendFormat(_L("%f\t"),aRowSet.ColReal32(ii)); + break; + case EDbColReal64: + line.AppendFormat(_L("%f\t"),aRowSet.ColReal64(ii)); + break; + case EDbColText: + line.Append(aRowSet.ColDes(ii)); + line.Append('\t'); + break; + case EDbColDateTime: + { + TDateTime time(aRowSet.ColTime(ii).DateTime()); + line.AppendFormat(_L("%d:%d:%d %d/%d/%d"),time.Hour(),time.Minute(),time.Second(),time.Day(),time.Month(),time.Year()); + } + break; + case EDbColLongText: + { + RDbColReadStream blob; + blob.OpenLC(aRowSet,ii); + TScriptLine text; + blob.ReadL(text,aRowSet.ColLength(ii)); + CleanupStack::PopAndDestroy(); + line.AppendFormat(_L("%S\t"),&text); + } + default: + break; + } + } + iScript.WriteLine(line); + } + iScript.WriteLine(TPtrC()); + delete colset; + } + + +// +// Create the database +// +LOCAL_C void CreateDatabase() + { + TEST2(TheDatabase.Replace(TheFs,KTestDatabase), KErrNone); + } + +// +// Close the database +// +LOCAL_C void CloseDatabase() + { + TheDatabase.Close(); + } + +// +// Prepare the test directory. +// +LOCAL_C void SetupTestDirectory() + { + TInt err=TheFs.Connect(); + TEST2(err, KErrNone); +// + err=TheFs.MkDir(KTestDatabase); + TEST(err==KErrNone || err==KErrAlreadyExists); + } + +// +// Initialise the cleanup stack. +// +LOCAL_C void SetupCleanup() + { + TheTrapCleanup=CTrapCleanup::New(); + TEST(TheTrapCleanup!=NULL); + TRAPD(err,\ + {\ + for (TInt i=KTestCleanupStack;i>0;i--)\ + CleanupStack::PushL((TAny*)0);\ + CleanupStack::Pop(KTestCleanupStack);\ + }); + TEST2(err, KErrNone); + } + +/** +@SYMTestCaseID SYSLIB-DBMS-CT-0632 +@SYMTestCaseDesc Executes the script files +@SYMTestPriority Medium +@SYMTestActions Start the script engine +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +LOCAL_C void RunScriptL() + { + TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0632 Running script ")); + CreateDatabase(); + TScriptEngine script; + script.RunL(); + CloseDatabase(); + TheView.Close(); + } + +// +// entry point +// +GLDEF_C TInt E32Main() + { + TheTest.Title(); + SetupTestDirectory(); + SetupCleanup(); + __UHEAP_MARK; +// + TRAPD(err,RunScriptL()); + TEST2(err, KErrNone); + + //deletion of data files must be done before call to end - DEF047652 + ::DeleteDataFile(KTestDatabase); + ::DeleteDataFile(KOutputFile);//Comment this line if you want to keep "t_script.log" file. + TheTest.End(); +// + __UHEAP_MARKEND; + delete TheTrapCleanup; + + TheFs.Close(); + TheTest.Close(); + + return 0; + }