sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: // MSVC++ up to 5.0 has problems with expanding inline functions sl@0: // This disables the mad warnings for the whole project sl@0: #if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100 sl@0: #pragma warning(disable : 4710) // function not expanded. MSVC 5.0 is stupid sl@0: #endif sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "crccheck.h" sl@0: sl@0: #undef __UHEAP_MARK sl@0: #define __UHEAP_MARK sl@0: #undef __UHEAP_MARKEND sl@0: #define __UHEAP_MARKEND sl@0: sl@0: LOCAL_D TDBMS_CRCChecks TheCrcChecker; sl@0: sl@0: #ifndef __linux__ //No CRC test on LINUX sl@0: #ifdef __TOOLS2__ sl@0: const TPtrC KCrcRecord=_L("\\epoc32\\winscw\\c\\dbms-tst\\T_TRANS.CRC"); sl@0: #else sl@0: const TPtrC KCrcRecord=_L("C:\\dbms-tst\\T_TRANS.CRC"); sl@0: #endif sl@0: #endif sl@0: sl@0: LOCAL_D RTest test(_L("T_TRANS - Test DBMS transactions")); sl@0: LOCAL_D CTrapCleanup* TheTrapCleanup; sl@0: LOCAL_D RDbTable TheTable; sl@0: LOCAL_D RFs TheFs; sl@0: #ifndef __TOOLS2__ sl@0: LOCAL_D RDbs TheDbs; sl@0: #endif sl@0: LOCAL_D RDbNamedDatabase TheDatabase; sl@0: sl@0: const TInt KTestCleanupStack=0x20; sl@0: sl@0: #ifdef __TOOLS2__ sl@0: const TPtrC KTestDatabase=_L(".\\dbms-tst\\T_TRANS.DB"); sl@0: #else sl@0: const TPtrC KTestDatabase=_L("C:\\dbms-tst\\T_TRANS.DB"); sl@0: #endif sl@0: sl@0: const TPtrC KTableName(_S("table")); sl@0: const TPtrC KIndexInt=_S("int"); sl@0: const TPtrC KIndexText=_S("text"); sl@0: const TPtrC KColumnInt=_S("int"); sl@0: const TPtrC KColumnText=_S("text"); sl@0: const TPtrC KColumnComment=_S("comment"); sl@0: const TPtrC KCommentValue=_S("abcdefghijklmnopqrstuvwxyz"); sl@0: const TInt KRecords=2000; sl@0: sl@0: class Progress sl@0: { sl@0: enum {ETotal=32}; sl@0: public: sl@0: Progress(TInt aCount); sl@0: void Next(TInt aStep); sl@0: private: sl@0: TInt iCount; sl@0: TInt iPos; sl@0: }; sl@0: sl@0: Progress::Progress(TInt aCount) sl@0: : iCount(aCount),iPos(0) sl@0: {} sl@0: sl@0: void Progress::Next(TInt aStep) sl@0: { sl@0: TInt next=(ETotal*(iCount-aStep))/iCount; sl@0: if (next!=iPos) sl@0: { sl@0: test.Printf(_L(".")); sl@0: iPos=next; sl@0: } sl@0: if (aStep==0) sl@0: test.Printf(_L("\n")); sl@0: } sl@0: sl@0: LOCAL_C void ProgressInc(RDbIncremental& inc,TInt aCount) sl@0: { sl@0: Progress progress(aCount); sl@0: while (aCount) sl@0: { sl@0: inc.Next(aCount); sl@0: progress.Next(aCount); sl@0: } sl@0: inc.Close(); sl@0: } sl@0: sl@0: LOCAL_C void CreateDatabaseL() sl@0: // sl@0: // Create the database sl@0: // sl@0: { sl@0: TInt r=TheDatabase.Replace(TheFs,KTestDatabase); sl@0: test (r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void OpenDatabase() sl@0: // sl@0: // Create the database sl@0: // sl@0: { sl@0: TInt r=TheDatabase.Open(TheFs,KTestDatabase); sl@0: test (r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void CloseDatabaseL() sl@0: { sl@0: TheDatabase.Close(); sl@0: TheCrcChecker.GenerateCrcL(KTestDatabase); sl@0: } sl@0: sl@0: LOCAL_C void CreateTable() sl@0: { sl@0: TInt r=TheDatabase.Execute(_L("create table table (int integer,text varchar(8),comment varchar)")); sl@0: test (r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void WriteRecords(TInt aCount) sl@0: { sl@0: Progress write(aCount); sl@0: TDbColNo cInt,cText,cComment; sl@0: CDbColSet* set=TheTable.ColSetL(); sl@0: cInt=set->ColNo(KColumnInt); sl@0: cText=set->ColNo(KColumnText); sl@0: cComment=set->ColNo(KColumnComment); sl@0: delete set; sl@0: TBuf<10> text; sl@0: TInt jj=0; sl@0: for (TInt ii=0;ii=aCount) sl@0: jj-=aCount; sl@0: TheTable.SetColL(cInt,jj); sl@0: text.Num(jj); sl@0: TheTable.SetColL(cText,text); sl@0: TheTable.SetColL(cComment,KCommentValue); sl@0: TheTable.PutL(); sl@0: write.Next(aCount-ii-1); sl@0: } sl@0: } sl@0: sl@0: LOCAL_C TUint FileSize() sl@0: { sl@0: #ifndef __TOOLS2__ sl@0: TEntry entry; sl@0: test(TheFs.Entry(KTestDatabase,entry)==KErrNone); sl@0: return entry.iSize; sl@0: #else sl@0: RFile myfile; sl@0: test(myfile.Open(TheFs, KTestDatabase, EFileRead) == KErrNone); sl@0: TInt size; sl@0: test(myfile.Size(size) == KErrNone); sl@0: myfile.Close(); sl@0: return size; sl@0: #endif sl@0: } sl@0: sl@0: LOCAL_C void BuildTable(TInt aCount,TBool aTransactions,TUint& aTime,TUint& aSize) sl@0: { sl@0: TUint size=FileSize(); sl@0: TUint time=User::TickCount(); sl@0: CreateTable(); sl@0: if (aTransactions) sl@0: TheDatabase.Begin(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: WriteRecords(aCount); sl@0: if (aTransactions) sl@0: test(TheDatabase.Commit()==KErrNone); sl@0: TheTable.Close(); sl@0: aTime=User::TickCount()-time; sl@0: aSize=FileSize()-size; sl@0: } sl@0: sl@0: LOCAL_C void Execute(const TDesC& aSql) sl@0: { sl@0: RDbIncremental inc; sl@0: TInt step; sl@0: test(inc.Execute(TheDatabase,aSql,step)==KErrNone); sl@0: ProgressInc(inc,step); sl@0: } sl@0: sl@0: LOCAL_C void BreakIndex() sl@0: { sl@0: TheDatabase.Begin(); sl@0: test(TheTable.Open(TheDatabase,KTableName)==KErrNone); sl@0: TheTable.InsertL(); sl@0: TheTable.SetColL(1,-1); sl@0: TheTable.PutL(); sl@0: TheTable.Close(); sl@0: TheDatabase.Rollback(); sl@0: test(TheDatabase.IsDamaged()); sl@0: } sl@0: sl@0: LOCAL_C void Recover() sl@0: { sl@0: RDbIncremental rec; sl@0: TInt step; sl@0: test(rec.Recover(TheDatabase,step)==KErrNone); sl@0: ProgressInc(rec,step); sl@0: test(!TheDatabase.IsDamaged()); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-DBMS-CT-0637 sl@0: @SYMTestCaseDesc Streaming conversions test sl@0: @SYMTestPriority Medium sl@0: @SYMTestActions Test the database definition and enquiry functions sl@0: @SYMTestExpectedResults Test must not fail sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void Test() sl@0: { sl@0: test.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0637 Build without transactions ")); sl@0: CreateDatabaseL(); sl@0: TUint time1,size1; sl@0: BuildTable(KRecords,EFalse,time1,size1); sl@0: CloseDatabaseL(); sl@0: test.Next(_L("Build with transactions")); sl@0: CreateDatabaseL(); sl@0: TUint time2,size2; sl@0: BuildTable(KRecords,ETrue,time2,size2); sl@0: test.Printf(_L("Transaction performance: time %4.2f, size %4.2f\n"),TReal(time1)/TReal(time2),TReal(size1)/TReal(size2)); sl@0: test.Next(_L("Build Int index")); sl@0: Execute(_L("create unique index int on table (int)")); sl@0: test.Next(_L("Break index")); sl@0: BreakIndex(); sl@0: test.Next(_L("Build Text index")); sl@0: Execute(_L("create unique index text on table (text)")); sl@0: test.Next(_L("Recover")); sl@0: test (TheDatabase.IsDamaged()); sl@0: CloseDatabaseL(); sl@0: OpenDatabase(); sl@0: test (TheDatabase.IsDamaged()); sl@0: Recover(); sl@0: test.Next(_L("Drop table")); sl@0: Execute(_L("drop table table")); sl@0: CloseDatabaseL(); sl@0: } sl@0: sl@0: LOCAL_C void setupTestDirectory() sl@0: // sl@0: // Prepare the test directory. sl@0: // sl@0: { sl@0: TInt r=TheFs.Connect(); sl@0: test(r==KErrNone); sl@0: // sl@0: r=TheFs.MkDir(KTestDatabase); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: } sl@0: sl@0: LOCAL_C void setupCleanup() sl@0: // sl@0: // Initialise the cleanup stack. sl@0: // sl@0: { sl@0: TheTrapCleanup=CTrapCleanup::New(); sl@0: test(TheTrapCleanup!=NULL); sl@0: TRAPD(r,\ sl@0: {\ sl@0: for (TInt i=KTestCleanupStack;i>0;i--)\ sl@0: CleanupStack::PushL((TAny*)0);\ sl@0: CleanupStack::Pop(KTestCleanupStack);\ sl@0: }); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: LOCAL_C void DeleteDataFile(const TDesC& aFullName) sl@0: { sl@0: RFs fsSession; sl@0: TInt err = fsSession.Connect(); sl@0: if(err == KErrNone) sl@0: { sl@0: TEntry entry; sl@0: if(fsSession.Entry(aFullName, entry) == KErrNone) sl@0: { sl@0: RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); sl@0: err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); sl@0: } sl@0: err = fsSession.Delete(aFullName); sl@0: if(err != KErrNone) sl@0: { sl@0: RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: fsSession.Close(); sl@0: } sl@0: else sl@0: { sl@0: RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); sl@0: } sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: test.Title(); sl@0: setupTestDirectory(); sl@0: setupCleanup(); sl@0: __UHEAP_MARK; sl@0: sl@0: TRAPD(r,Test();) sl@0: test(r==KErrNone); sl@0: sl@0: test.Printf(_L("Waiting for server exit\n")); sl@0: const TUint KExitDelay=6*0x100000; // ~6 seconds sl@0: User::After(KExitDelay); sl@0: sl@0: //deletion of data files must be done before call to End() - DEF047652 sl@0: ::DeleteDataFile(KTestDatabase); sl@0: sl@0: #ifndef __linux__ sl@0: TInt err; sl@0: #ifndef __TOOLS2__ sl@0: TRAPD(lc, err = TheCrcChecker.DumpCrcRecordsL(KCrcRecord)); sl@0: test(err==KErrNone); sl@0: test(lc==KErrNone); sl@0: #else sl@0: TRAPD(lc, err = TheCrcChecker.ValidateCrcRecordsL(KCrcRecord)); sl@0: TPtrC errmsg; sl@0: TheCrcChecker.ErrorReportL(err, errmsg); sl@0: RDebug::Print(errmsg); sl@0: test(err==KErrNone || err==TDBMS_CRCChecks::ECrcCheckOk); sl@0: #endif sl@0: #endif sl@0: sl@0: test.End(); sl@0: // sl@0: __UHEAP_MARKEND; sl@0: sl@0: delete TheTrapCleanup; sl@0: TheFs.Close(); sl@0: test.Close(); sl@0: return 0; sl@0: }