1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/dbms/tdbms/t_dbtrans.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,384 @@
1.4 +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +#include <d32dbms.h>
1.19 +#include <s32file.h>
1.20 +#include <e32test.h>
1.21 +#include <e32math.h>
1.22 +#include <hal.h>
1.23 +
1.24 +static RTest TheTest(_L("t_dbtrans: Test DBMS transactions"));
1.25 +static RDbTable TheTable;
1.26 +static RFs TheFs;
1.27 +static RDbs TheDbs;
1.28 +static RDbNamedDatabase TheDatabase;
1.29 +
1.30 +static TFileName TheTestDbFileName;
1.31 +
1.32 +const TPtrC KTableName(_S("table"));
1.33 +const TPtrC KIndexInt=_S("int");
1.34 +const TPtrC KIndexText=_S("text");
1.35 +const TPtrC KColumnInt=_S("int");
1.36 +const TPtrC KColumnText=_S("text");
1.37 +const TPtrC KColumnComment=_S("comment");
1.38 +const TPtrC KCommentValue=_S("abcdefghijklmnopqrstuvwxyz");
1.39 +const TInt KRecords=2000;
1.40 +
1.41 +///////////////////////////////////////////////////////////////////////////////////////
1.42 +
1.43 +static void CloseAll()
1.44 + {
1.45 + TheTable.Close();
1.46 + TheDatabase.Close();
1.47 + TheDbs.Close();
1.48 + }
1.49 +
1.50 +///////////////////////////////////////////////////////////////////////////////////////
1.51 +
1.52 +//Delete "aFullName" file.
1.53 +static void DeleteFile(const TDesC& aFullName)
1.54 + {
1.55 + RFs fsSession;
1.56 + TInt err = fsSession.Connect();
1.57 + if(err == KErrNone)
1.58 + {
1.59 + TEntry entry;
1.60 + if(fsSession.Entry(aFullName, entry) == KErrNone)
1.61 + {
1.62 + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
1.63 + if(err != KErrNone)
1.64 + {
1.65 + TheTest.Printf(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
1.66 + }
1.67 + err = fsSession.Delete(aFullName);
1.68 + if(err != KErrNone)
1.69 + {
1.70 + TheTest.Printf(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
1.71 + }
1.72 + }
1.73 + fsSession.Close();
1.74 + }
1.75 + else
1.76 + {
1.77 + TheTest.Printf(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
1.78 + }
1.79 + }
1.80 +
1.81 +///////////////////////////////////////////////////////////////////////////////////////
1.82 +
1.83 +static void DestroyTestEnv()
1.84 + {
1.85 + CloseAll();
1.86 + DeleteFile(TheTestDbFileName);
1.87 + TheFs.Close();
1.88 + }
1.89 +
1.90 +///////////////////////////////////////////////////////////////////////////////////////
1.91 +//Tests macros and functions.
1.92 +//If (!aValue) then the test will be panicked, the test data files will be deleted.
1.93 +static void Check(TInt aValue, TInt aLine)
1.94 + {
1.95 + if(!aValue)
1.96 + {
1.97 + TheTest.Printf(_L("*** Boolean expression evaluated to false!\r\n"));
1.98 + DestroyTestEnv();
1.99 + TheTest(EFalse, aLine);
1.100 + }
1.101 + }
1.102 +//If (aValue != aExpected) then the test will be panicked, the test data files will be deleted.
1.103 +static void Check(TInt aValue, TInt aExpected, TInt aLine)
1.104 + {
1.105 + if(aValue != aExpected)
1.106 + {
1.107 + TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
1.108 + DestroyTestEnv();
1.109 + TheTest(EFalse, aLine);
1.110 + }
1.111 + }
1.112 +//Use these to test conditions.
1.113 +#define TEST(arg) ::Check((arg), __LINE__)
1.114 +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
1.115 +
1.116 +//////////////////////////////////////////////////////
1.117 +
1.118 +static TInt TheCounterFreq = -10000000;
1.119 +const TInt KMicroSecIn1Sec = 1000000;
1.120 +
1.121 +TUint32 CalcTickDiff(TUint32 aStartTicks, TUint32 aEndTicks)
1.122 + {
1.123 + TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
1.124 + if(diffTicks < 0)
1.125 + {
1.126 + diffTicks = KMaxTUint32 + diffTicks + 1;
1.127 + }
1.128 + return (TUint32)diffTicks;
1.129 + }
1.130 +
1.131 +//Prints aFastCount parameter (converted to us)
1.132 +void PrintFcDiffAsUs(const TDesC& aFormatStr, TUint32 aFastCount)
1.133 + {
1.134 + if(TheCounterFreq <= 0)
1.135 + {
1.136 + TEST2(HAL::Get(HAL::EFastCounterFrequency, TheCounterFreq), KErrNone);
1.137 + TheTest.Printf(_L("Counter frequency=%d Hz\r\n"), TheCounterFreq);
1.138 + }
1.139 + double v = ((double)aFastCount * KMicroSecIn1Sec) / (double)TheCounterFreq;
1.140 + TInt v2 = (TInt)v;
1.141 + TheTest.Printf(aFormatStr, v2);
1.142 + }
1.143 +
1.144 +///////////////////////////////////////////////////////////////////////////////////////
1.145 +
1.146 +//
1.147 +// Prepare the test directory.
1.148 +//
1.149 +void CreateTestEnv()
1.150 + {
1.151 + TInt err = TheFs.Connect();
1.152 + TheTest(err == KErrNone);
1.153 +
1.154 + err = TheFs.MkDirAll(TheTestDbFileName);
1.155 + TEST(err == KErrNone || err == KErrAlreadyExists);
1.156 + }
1.157 +
1.158 +///////////////////////////////////////////////////////////////////////////////////////
1.159 +
1.160 +class Progress
1.161 + {
1.162 + enum {ETotal=32};
1.163 +public:
1.164 + Progress(TInt aCount);
1.165 + void Next(TInt aStep);
1.166 +private:
1.167 + TInt iCount;
1.168 + TInt iPos;
1.169 + };
1.170 +
1.171 +Progress::Progress(TInt aCount)
1.172 + : iCount(aCount),iPos(0)
1.173 + {}
1.174 +
1.175 +void Progress::Next(TInt aStep)
1.176 + {
1.177 + TInt next=(ETotal*(iCount-aStep))/iCount;
1.178 + if (next!=iPos)
1.179 + {
1.180 + iPos=next;
1.181 + }
1.182 + }
1.183 +
1.184 +static void ProgressInc(RDbIncremental& inc,TInt aCount)
1.185 + {
1.186 + Progress progress(aCount);
1.187 + while (aCount)
1.188 + {
1.189 + inc.Next(aCount);
1.190 + progress.Next(aCount);
1.191 + }
1.192 + inc.Close();
1.193 + }
1.194 +
1.195 +//
1.196 +// Create the database
1.197 +//
1.198 +static void CreateDatabase()
1.199 + {
1.200 + TInt err = TheDatabase.Replace(TheFs, TheTestDbFileName);
1.201 + TEST2(err, KErrNone);
1.202 + }
1.203 +
1.204 +//
1.205 +// Create the database
1.206 +//
1.207 +static void OpenDatabase()
1.208 + {
1.209 + TInt err = TheDatabase.Open(TheFs, TheTestDbFileName);
1.210 + TEST2(err, KErrNone);
1.211 + }
1.212 +
1.213 +static void CloseDatabase()
1.214 + {
1.215 + TheDatabase.Close();
1.216 + }
1.217 +
1.218 +static void CreateTable()
1.219 + {
1.220 + TInt err = TheDatabase.Execute(_L("create table table (int integer,text varchar(8),comment varchar)"));
1.221 + TEST2(err, KErrNone);
1.222 + }
1.223 +
1.224 +static void WriteRecordsL(TInt aCount)
1.225 + {
1.226 + Progress write(aCount);
1.227 + TDbColNo cInt,cText,cComment;
1.228 + CDbColSet* set=TheTable.ColSetL();
1.229 + cInt=set->ColNo(KColumnInt);
1.230 + cText=set->ColNo(KColumnText);
1.231 + cComment=set->ColNo(KColumnComment);
1.232 + delete set;
1.233 + TBuf<10> text;
1.234 + TInt jj=0;
1.235 + for (TInt ii=0;ii<aCount;++ii)
1.236 + {
1.237 + TheTable.InsertL();
1.238 + jj=(jj+23);
1.239 + if (jj>=aCount)
1.240 + jj-=aCount;
1.241 + TheTable.SetColL(cInt,jj);
1.242 + text.Num(jj);
1.243 + TheTable.SetColL(cText,text);
1.244 + TheTable.SetColL(cComment,KCommentValue);
1.245 + TheTable.PutL();
1.246 + write.Next(aCount-ii-1);
1.247 + }
1.248 + }
1.249 +
1.250 +static TUint FileSize()
1.251 + {
1.252 + TEntry entry;
1.253 + TEST2(TheFs.Entry(TheTestDbFileName, entry), KErrNone);
1.254 + return entry.iSize;
1.255 + }
1.256 +
1.257 +static void BuildTableL(TInt aCount, TBool aTransactions, TUint32& aTicks, TUint& aSize)
1.258 + {
1.259 + TUint size = FileSize();
1.260 + TUint fc = User::FastCounter();
1.261 + CreateTable();
1.262 + if(aTransactions)
1.263 + {
1.264 + TheDatabase.Begin();
1.265 + }
1.266 + TEST2(TheTable.Open(TheDatabase, KTableName), KErrNone);
1.267 + WriteRecordsL(aCount);
1.268 + if(aTransactions)
1.269 + {
1.270 + TEST2(TheDatabase.Commit(), KErrNone);
1.271 + }
1.272 + TheTable.Close();
1.273 + aTicks = CalcTickDiff(fc, User::FastCounter());
1.274 + aSize = FileSize() - size;
1.275 + }
1.276 +
1.277 +static void Execute(const TDesC& aSql)
1.278 + {
1.279 + RDbIncremental inc;
1.280 + TInt step;
1.281 + TEST2(inc.Execute(TheDatabase,aSql,step), KErrNone);
1.282 + ProgressInc(inc,step);
1.283 + }
1.284 +
1.285 +static void BreakIndexL()
1.286 + {
1.287 + TheDatabase.Begin();
1.288 + TEST2(TheTable.Open(TheDatabase,KTableName), KErrNone);
1.289 + TheTable.InsertL();
1.290 + TheTable.SetColL(1,-1);
1.291 + TheTable.PutL();
1.292 + TheTable.Close();
1.293 + TheDatabase.Rollback();
1.294 + TEST(TheDatabase.IsDamaged());
1.295 + }
1.296 +
1.297 +LOCAL_C void Recover()
1.298 + {
1.299 + RDbIncremental rec;
1.300 + TInt step;
1.301 + TEST2(rec.Recover(TheDatabase,step), KErrNone);
1.302 + ProgressInc(rec,step);
1.303 + TEST(!TheDatabase.IsDamaged());
1.304 + }
1.305 +
1.306 +/**
1.307 +@SYMTestCaseID SYSLIB-DBMS-CT-0637
1.308 +@SYMTestCaseDesc Streaming conversions test
1.309 +@SYMTestPriority Medium
1.310 +@SYMTestActions Test the database definition and enquiry functions
1.311 +@SYMTestExpectedResults Test must not fail
1.312 +@SYMREQ REQ0000
1.313 +*/
1.314 +static void TestL()
1.315 + {
1.316 + TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0637 Build without transactions "));
1.317 + CreateDatabase();
1.318 + TUint32 ticks1;
1.319 + TUint size1;
1.320 + BuildTableL(KRecords, EFalse, ticks1, size1);
1.321 + CloseDatabase();
1.322 +
1.323 + TheTest.Next(_L("Build with transactions"));
1.324 + CreateDatabase();
1.325 + TUint32 ticks2;
1.326 + TUint size2;
1.327 + BuildTableL(KRecords, ETrue, ticks2, size2);
1.328 +
1.329 + PrintFcDiffAsUs(_L("#### Without transactions, time=%d us\n"), ticks1);
1.330 + PrintFcDiffAsUs(_L("#### With transactions, time=%d us\n"), ticks2);
1.331 + 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));
1.332 +
1.333 + TheTest.Next(_L("Build Int index"));
1.334 + Execute(_L("create unique index int on table (int)"));
1.335 +
1.336 + TheTest.Next(_L("Break index"));
1.337 + BreakIndexL();
1.338 +
1.339 + TheTest.Next(_L("Build Text index"));
1.340 + Execute(_L("create unique index text on table (text)"));
1.341 +
1.342 + TheTest.Next(_L("Recover"));
1.343 + TEST(TheDatabase.IsDamaged());
1.344 +
1.345 + CloseDatabase();
1.346 + OpenDatabase();
1.347 + TEST(TheDatabase.IsDamaged());
1.348 + Recover();
1.349 +
1.350 + TheTest.Next(_L("Drop table"));
1.351 + Execute(_L("drop table table"));
1.352 + CloseDatabase();
1.353 + }
1.354 +
1.355 +//Usage: "t_trans [<drive letter>:]]"
1.356 +TInt E32Main()
1.357 + {
1.358 + TheTest.Title();
1.359 +
1.360 + CTrapCleanup* tc = CTrapCleanup::New();
1.361 + TheTest(tc != NULL);
1.362 +
1.363 + TBuf<256> cmdline;
1.364 + User::CommandLine(cmdline);
1.365 +
1.366 + TParse parse;
1.367 +
1.368 + _LIT(KTestDatabase, "C:\\DBMS-TST\\T_TRANS.DB");
1.369 + parse.Set(cmdline, &KTestDatabase, 0);
1.370 + TheTestDbFileName.Copy(parse.FullName());
1.371 +
1.372 + __UHEAP_MARK;
1.373 +
1.374 + CreateTestEnv();
1.375 + TRAPD(err, TestL());
1.376 + TEST2(err, KErrNone);
1.377 + DestroyTestEnv();
1.378 +
1.379 + delete tc;
1.380 +
1.381 + __UHEAP_MARKEND;
1.382 +
1.383 + TheTest.End();
1.384 + TheTest.Close();
1.385 +
1.386 + return 0;
1.387 + }