persistentstorage/dbms/tdbms/t_dbtrans.cpp
changeset 0 08ec8eefde2f
child 55 44f437012c90
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 #include <d32dbms.h>
       
    16 #include <s32file.h>
       
    17 #include <e32test.h>
       
    18 #include <e32math.h>
       
    19 #include <hal.h>
       
    20 
       
    21 static RTest TheTest(_L("t_dbtrans: Test DBMS transactions"));
       
    22 static RDbTable TheTable;
       
    23 static RFs TheFs;
       
    24 static RDbs TheDbs;
       
    25 static RDbNamedDatabase TheDatabase;
       
    26 
       
    27 static TFileName TheTestDbFileName;
       
    28 
       
    29 const TPtrC KTableName(_S("table"));
       
    30 const TPtrC KIndexInt=_S("int");
       
    31 const TPtrC KIndexText=_S("text");
       
    32 const TPtrC KColumnInt=_S("int");
       
    33 const TPtrC KColumnText=_S("text");
       
    34 const TPtrC KColumnComment=_S("comment");
       
    35 const TPtrC KCommentValue=_S("abcdefghijklmnopqrstuvwxyz");
       
    36 const TInt KRecords=2000;
       
    37 
       
    38 ///////////////////////////////////////////////////////////////////////////////////////
       
    39 
       
    40 static void CloseAll()
       
    41 	{
       
    42 	TheTable.Close();
       
    43 	TheDatabase.Close();
       
    44 	TheDbs.Close();
       
    45 	}
       
    46 
       
    47 ///////////////////////////////////////////////////////////////////////////////////////
       
    48 
       
    49 //Delete "aFullName" file.
       
    50 static void DeleteFile(const TDesC& aFullName)
       
    51 	{
       
    52 	RFs fsSession;
       
    53 	TInt err = fsSession.Connect();
       
    54 	if(err == KErrNone)
       
    55 		{
       
    56 		TEntry entry;
       
    57 		if(fsSession.Entry(aFullName, entry) == KErrNone)
       
    58 			{
       
    59 			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
       
    60 			if(err != KErrNone) 
       
    61 				{
       
    62 				TheTest.Printf(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
       
    63 				}
       
    64 			err = fsSession.Delete(aFullName);
       
    65 			if(err != KErrNone) 
       
    66 				{
       
    67 				TheTest.Printf(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
       
    68 				}
       
    69 			}
       
    70 		fsSession.Close();
       
    71 		}
       
    72 	else
       
    73 		{
       
    74 		TheTest.Printf(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
       
    75 		}
       
    76 	}
       
    77 
       
    78 ///////////////////////////////////////////////////////////////////////////////////////
       
    79 
       
    80 static void DestroyTestEnv()
       
    81 	{
       
    82 	CloseAll();
       
    83 	DeleteFile(TheTestDbFileName);
       
    84 	TheFs.Close();
       
    85 	}
       
    86 
       
    87 ///////////////////////////////////////////////////////////////////////////////////////
       
    88 //Tests macros and functions.
       
    89 //If (!aValue) then the test will be panicked, the test data files will be deleted.
       
    90 static void Check(TInt aValue, TInt aLine)
       
    91 	{
       
    92 	if(!aValue)
       
    93 		{
       
    94 		TheTest.Printf(_L("*** Boolean expression evaluated to false!\r\n"));
       
    95 		DestroyTestEnv();
       
    96 		TheTest(EFalse, aLine);
       
    97 		}
       
    98 	}
       
    99 //If (aValue != aExpected) then the test will be panicked, the test data files will be deleted.
       
   100 static void Check(TInt aValue, TInt aExpected, TInt aLine)
       
   101 	{
       
   102 	if(aValue != aExpected)
       
   103 		{
       
   104 		TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
   105 		DestroyTestEnv();
       
   106 		TheTest(EFalse, aLine);
       
   107 		}
       
   108 	}
       
   109 //Use these to test conditions.
       
   110 #define TEST(arg) ::Check((arg), __LINE__)
       
   111 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
   112 
       
   113 //////////////////////////////////////////////////////
       
   114 
       
   115 static TInt TheCounterFreq = -10000000;
       
   116 const TInt KMicroSecIn1Sec = 1000000;
       
   117 
       
   118 TUint32 CalcTickDiff(TUint32 aStartTicks, TUint32 aEndTicks)
       
   119 	{
       
   120 	TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
       
   121 	if(diffTicks < 0)
       
   122 		{
       
   123 		diffTicks = KMaxTUint32 + diffTicks + 1;
       
   124 		}
       
   125 	return (TUint32)diffTicks;
       
   126 	}
       
   127 
       
   128 //Prints aFastCount parameter (converted to us)
       
   129 void PrintFcDiffAsUs(const TDesC& aFormatStr, TUint32 aFastCount)
       
   130 	{
       
   131 	if(TheCounterFreq <= 0)
       
   132 		{
       
   133 		TEST2(HAL::Get(HAL::EFastCounterFrequency, TheCounterFreq), KErrNone);
       
   134 		TheTest.Printf(_L("Counter frequency=%d Hz\r\n"), TheCounterFreq);
       
   135 		}
       
   136 	double v = ((double)aFastCount * KMicroSecIn1Sec) / (double)TheCounterFreq;
       
   137 	TInt v2 = (TInt)v;
       
   138 	TheTest.Printf(aFormatStr, v2);
       
   139 	}
       
   140 
       
   141 ///////////////////////////////////////////////////////////////////////////////////////
       
   142 
       
   143 //
       
   144 // Prepare the test directory.
       
   145 //
       
   146 void CreateTestEnv()
       
   147     {
       
   148 	TInt err = TheFs.Connect();
       
   149 	TheTest(err == KErrNone);
       
   150 
       
   151 	err = TheFs.MkDirAll(TheTestDbFileName);
       
   152 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   153 	}
       
   154 
       
   155 ///////////////////////////////////////////////////////////////////////////////////////
       
   156 
       
   157 class Progress
       
   158 	{
       
   159 	enum {ETotal=32};
       
   160 public:
       
   161 	Progress(TInt aCount);
       
   162 	void Next(TInt aStep);
       
   163 private:
       
   164 	TInt iCount;
       
   165 	TInt iPos;
       
   166 	};
       
   167 
       
   168 Progress::Progress(TInt aCount)
       
   169 	: iCount(aCount),iPos(0)
       
   170 	{}
       
   171 
       
   172 void Progress::Next(TInt aStep)
       
   173 	{
       
   174 	TInt next=(ETotal*(iCount-aStep))/iCount;
       
   175 	if (next!=iPos)
       
   176 		{
       
   177 		iPos=next;
       
   178 		}
       
   179 	}
       
   180 
       
   181 static void ProgressInc(RDbIncremental& inc,TInt aCount)
       
   182 	{
       
   183 	Progress progress(aCount);
       
   184 	while (aCount)
       
   185 		{
       
   186 		inc.Next(aCount);
       
   187 		progress.Next(aCount);
       
   188 		}
       
   189 	inc.Close();
       
   190 	}
       
   191 
       
   192 //
       
   193 // Create the database
       
   194 //
       
   195 static void CreateDatabase()
       
   196 	{
       
   197 	TInt err = TheDatabase.Replace(TheFs, TheTestDbFileName);
       
   198 	TEST2(err, KErrNone);
       
   199 	}
       
   200 
       
   201 //
       
   202 // Create the database
       
   203 //
       
   204 static void OpenDatabase()
       
   205 	{
       
   206 	TInt err = TheDatabase.Open(TheFs, TheTestDbFileName);
       
   207 	TEST2(err, KErrNone);
       
   208 	}
       
   209 
       
   210 static void CloseDatabase()
       
   211 	{
       
   212 	TheDatabase.Close();
       
   213 	}
       
   214 
       
   215 static void CreateTable()
       
   216 	{
       
   217 	TInt err = TheDatabase.Execute(_L("create table table (int integer,text varchar(8),comment varchar)"));
       
   218 	TEST2(err, KErrNone);
       
   219 	}
       
   220 
       
   221 static void WriteRecordsL(TInt aCount)
       
   222 	{
       
   223 	Progress write(aCount);
       
   224 	TDbColNo cInt,cText,cComment;
       
   225 	CDbColSet* set=TheTable.ColSetL();
       
   226 	cInt=set->ColNo(KColumnInt);
       
   227 	cText=set->ColNo(KColumnText);
       
   228 	cComment=set->ColNo(KColumnComment);
       
   229 	delete set;
       
   230 	TBuf<10> text;
       
   231 	TInt jj=0;
       
   232 	for (TInt ii=0;ii<aCount;++ii)
       
   233 		{
       
   234 		TheTable.InsertL();
       
   235 		jj=(jj+23);
       
   236 		if (jj>=aCount)
       
   237 			jj-=aCount;
       
   238 		TheTable.SetColL(cInt,jj);
       
   239 		text.Num(jj);
       
   240 		TheTable.SetColL(cText,text);
       
   241 		TheTable.SetColL(cComment,KCommentValue);
       
   242 		TheTable.PutL();
       
   243 		write.Next(aCount-ii-1);
       
   244 		}
       
   245 	}
       
   246 
       
   247 static TUint FileSize()
       
   248 	{
       
   249 	TEntry entry;
       
   250 	TEST2(TheFs.Entry(TheTestDbFileName, entry), KErrNone);
       
   251 	return entry.iSize;
       
   252 	}
       
   253 
       
   254 static void BuildTableL(TInt aCount, TBool aTransactions, TUint32& aTicks, TUint& aSize)
       
   255 	{
       
   256 	TUint size = FileSize();
       
   257 	TUint fc = User::FastCounter();
       
   258 	CreateTable();
       
   259 	if(aTransactions)
       
   260 		{
       
   261 		TheDatabase.Begin();
       
   262 		}
       
   263 	TEST2(TheTable.Open(TheDatabase, KTableName), KErrNone);
       
   264 	WriteRecordsL(aCount);
       
   265 	if(aTransactions)
       
   266 		{
       
   267 		TEST2(TheDatabase.Commit(), KErrNone);
       
   268 		}
       
   269 	TheTable.Close();
       
   270 	aTicks = CalcTickDiff(fc, User::FastCounter());
       
   271 	aSize = FileSize() - size;
       
   272 	}
       
   273 
       
   274 static void Execute(const TDesC& aSql)
       
   275 	{
       
   276 	RDbIncremental inc;
       
   277 	TInt step;
       
   278 	TEST2(inc.Execute(TheDatabase,aSql,step), KErrNone);
       
   279 	ProgressInc(inc,step);
       
   280 	}
       
   281 
       
   282 static void BreakIndexL()
       
   283 	{
       
   284 	TheDatabase.Begin();
       
   285 	TEST2(TheTable.Open(TheDatabase,KTableName), KErrNone);
       
   286 	TheTable.InsertL();
       
   287 	TheTable.SetColL(1,-1);
       
   288 	TheTable.PutL();
       
   289 	TheTable.Close();
       
   290 	TheDatabase.Rollback();
       
   291 	TEST(TheDatabase.IsDamaged());
       
   292 	}
       
   293 
       
   294 LOCAL_C void Recover()
       
   295 	{
       
   296 	RDbIncremental rec;
       
   297 	TInt step;
       
   298 	TEST2(rec.Recover(TheDatabase,step), KErrNone);
       
   299 	ProgressInc(rec,step);
       
   300 	TEST(!TheDatabase.IsDamaged());
       
   301 	}
       
   302 
       
   303 /**
       
   304 @SYMTestCaseID          SYSLIB-DBMS-CT-0637
       
   305 @SYMTestCaseDesc        Streaming conversions test
       
   306 @SYMTestPriority        Medium
       
   307 @SYMTestActions         Test the database definition and enquiry functions
       
   308 @SYMTestExpectedResults Test must not fail
       
   309 @SYMREQ                 REQ0000
       
   310 */
       
   311 static void TestL()
       
   312 	{
       
   313 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0637 Build without transactions "));
       
   314 	CreateDatabase();
       
   315 	TUint32 ticks1;
       
   316 	TUint size1;
       
   317 	BuildTableL(KRecords, EFalse, ticks1, size1);
       
   318 	CloseDatabase();
       
   319 	
       
   320 	TheTest.Next(_L("Build with transactions"));
       
   321 	CreateDatabase();
       
   322 	TUint32 ticks2;
       
   323 	TUint size2;
       
   324 	BuildTableL(KRecords, ETrue, ticks2, size2);
       
   325 	
       
   326 	PrintFcDiffAsUs(_L("#### Without transactions, time=%d us\n"), ticks1);
       
   327 	PrintFcDiffAsUs(_L("#### With    transactions, time=%d us\n"), ticks2);
       
   328 	TheTest.Printf(_L("Transaction performance ratio (without trn:with trn): time %4.2f, size %4.2f\n"), TReal(ticks1) / TReal(ticks2), TReal(size1) / TReal(size2));
       
   329 	
       
   330 	TheTest.Next(_L("Build Int index"));
       
   331 	Execute(_L("create unique index int on table (int)"));
       
   332 	
       
   333 	TheTest.Next(_L("Break index"));
       
   334 	BreakIndexL();
       
   335 	
       
   336 	TheTest.Next(_L("Build Text index"));
       
   337 	Execute(_L("create unique index text on table (text)"));
       
   338 	
       
   339 	TheTest.Next(_L("Recover"));
       
   340 	TEST(TheDatabase.IsDamaged());
       
   341 	
       
   342 	CloseDatabase();
       
   343 	OpenDatabase();
       
   344 	TEST(TheDatabase.IsDamaged());
       
   345 	Recover();
       
   346 	
       
   347 	TheTest.Next(_L("Drop table"));
       
   348 	Execute(_L("drop table table"));
       
   349 	CloseDatabase();
       
   350 	}
       
   351 
       
   352 //Usage: "t_trans [<drive letter>:]]"
       
   353 TInt E32Main()
       
   354     {
       
   355 	TheTest.Title();
       
   356 	
       
   357 	CTrapCleanup* tc = CTrapCleanup::New();
       
   358 	TheTest(tc != NULL);
       
   359 	
       
   360 	TBuf<256> cmdline;
       
   361 	User::CommandLine(cmdline);
       
   362 
       
   363 	TParse parse;
       
   364 
       
   365 	_LIT(KTestDatabase, "C:\\DBMS-TST\\T_TRANS.DB");
       
   366 	parse.Set(cmdline, &KTestDatabase, 0);
       
   367 	TheTestDbFileName.Copy(parse.FullName());
       
   368 	
       
   369 	__UHEAP_MARK;
       
   370 	
       
   371 	CreateTestEnv();
       
   372 	TRAPD(err, TestL());
       
   373 	TEST2(err, KErrNone);
       
   374 	DestroyTestEnv();
       
   375 
       
   376 	delete tc;
       
   377 
       
   378 	__UHEAP_MARKEND;
       
   379 	
       
   380 	TheTest.End();
       
   381 	TheTest.Close();
       
   382 	
       
   383 	return 0;
       
   384     }