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