persistentstorage/dbms/tdbms/t_dbcomp.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 
       
    16 // MSVC++ up to 5.0 has problems with expanding inline functions
       
    17 // This disables the mad warnings for the whole project
       
    18 #if defined(NDEBUG) && defined(__VC32__) && _MSC_VER<=1100
       
    19 #pragma warning(disable : 4710)			// function not expanded. MSVC 5.0 is stupid
       
    20 #endif
       
    21 
       
    22 #include <d32dbms.h>
       
    23 #include <s32file.h>
       
    24 #include <e32test.h>
       
    25 #include <e32math.h>
       
    26 #include <hal.h>
       
    27 
       
    28 static RTest TheTest(_L("t_dbcomp"));
       
    29 static RFs   TheFs;
       
    30 
       
    31 //T_BENCH.DB file is created by T_BENCH test and is used by the current test (T_COMP).
       
    32 //T_COMP test will delete T_BENCH.DB at the end as it is no more needed.
       
    33 //If you want to rerun T_COMP test again, you have to ensure that T_BENCH.DB file exists -
       
    34 //run T_BENCH test again.
       
    35 TFileName TheBenchDbFileName;
       
    36 TFileName TheCompressedFileName;
       
    37 TFileName TheDecompressedFileName;
       
    38 
       
    39 RDbNamedDatabase TheCompDb;
       
    40 RDbNamedDatabase TheCopyDb;
       
    41 RDbTable 		 TheTable1, TheTable2;
       
    42 
       
    43 ///////////////////////////////////////////////////////////////////////////////////////
       
    44 
       
    45 static void CloseAll()
       
    46 	{
       
    47 	TheTable2.Close();
       
    48 	TheTable1.Close();
       
    49 	TheCopyDb.Close();
       
    50 	TheCompDb.Close();
       
    51 	}
       
    52 
       
    53 ///////////////////////////////////////////////////////////////////////////////////////
       
    54 
       
    55 //Delete "aFullName" file.
       
    56 static void DeleteFile(const TDesC& aFullName)
       
    57 	{
       
    58 	RFs fsSession;
       
    59 	TInt err = fsSession.Connect();
       
    60 	if(err == KErrNone)
       
    61 		{
       
    62 		TEntry entry;
       
    63 		if(fsSession.Entry(aFullName, entry) == KErrNone)
       
    64 			{
       
    65 			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
       
    66 			if(err != KErrNone) 
       
    67 				{
       
    68 				TheTest.Printf(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
       
    69 				}
       
    70 			err = fsSession.Delete(aFullName);
       
    71 			if(err != KErrNone) 
       
    72 				{
       
    73 				TheTest.Printf(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
       
    74 				}
       
    75 			}
       
    76 		fsSession.Close();
       
    77 		}
       
    78 	else
       
    79 		{
       
    80 		TheTest.Printf(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
       
    81 		}
       
    82 	}
       
    83 
       
    84 ///////////////////////////////////////////////////////////////////////////////////////
       
    85 
       
    86 static void DestroyTestEnv()
       
    87 	{
       
    88 	CloseAll();
       
    89 	DeleteFile(TheDecompressedFileName);
       
    90 	DeleteFile(TheCompressedFileName);
       
    91 	DeleteFile(TheBenchDbFileName);
       
    92 	TheFs.Close();
       
    93 	}
       
    94 
       
    95 ///////////////////////////////////////////////////////////////////////////////////////
       
    96 //Tests macros and functions.
       
    97 //If (!aValue) then the test will be panicked, the test data files will be deleted.
       
    98 static void Check(TInt aValue, TInt aLine)
       
    99 	{
       
   100 	if(!aValue)
       
   101 		{
       
   102 		TheTest.Printf(_L("*** Boolean expression evaluated to false!\r\n"));
       
   103 		DestroyTestEnv();
       
   104 		TheTest(EFalse, aLine);
       
   105 		}
       
   106 	}
       
   107 //If (aValue != aExpected) then the test will be panicked, the test data files will be deleted.
       
   108 static void Check(TInt aValue, TInt aExpected, TInt aLine)
       
   109 	{
       
   110 	if(aValue != aExpected)
       
   111 		{
       
   112 		TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
   113 		DestroyTestEnv();
       
   114 		TheTest(EFalse, aLine);
       
   115 		}
       
   116 	}
       
   117 //Use these to test conditions.
       
   118 #define TEST(arg) ::Check((arg), __LINE__)
       
   119 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
   120 
       
   121 //////////////////////////////////////////////////////
       
   122 
       
   123 static TInt TheCounterFreq = -10000000;
       
   124 const TInt KMicroSecIn1Sec = 1000000;
       
   125 
       
   126 TUint32 CalcTickDiff(TUint32 aStartTicks, TUint32 aEndTicks)
       
   127 	{
       
   128 	TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
       
   129 	if(diffTicks < 0)
       
   130 		{
       
   131 		diffTicks = KMaxTUint32 + diffTicks + 1;
       
   132 		}
       
   133 	return (TUint32)diffTicks;
       
   134 	}
       
   135 
       
   136 //Prints aFastCount parameter (converted to us)
       
   137 void PrintFcDiffAsUs(const TDesC& aFormatStr, TUint32 aFastCount)
       
   138 	{
       
   139 	if(TheCounterFreq <= 0)
       
   140 		{
       
   141 		TEST2(HAL::Get(HAL::EFastCounterFrequency, TheCounterFreq), KErrNone);
       
   142 		TheTest.Printf(_L("Counter frequency=%d Hz\r\n"), TheCounterFreq);
       
   143 		}
       
   144 	double v = ((double)aFastCount * KMicroSecIn1Sec) / (double)TheCounterFreq;
       
   145 	TInt v2 = (TInt)v;
       
   146 	TheTest.Printf(aFormatStr, v2);
       
   147 	}
       
   148 
       
   149 ///////////////////////////////////////////////////////////////////////////////////////
       
   150 
       
   151 //
       
   152 // Prepare the test directory.
       
   153 //
       
   154 void CreateTestEnv()
       
   155     {
       
   156 	TInt err = TheFs.Connect();
       
   157 	TheTest(err == KErrNone);
       
   158 
       
   159 	err = TheFs.MkDirAll(TheBenchDbFileName);
       
   160 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   161 	
       
   162 	TUint dummy;
       
   163 	err = TheFs.Att(TheBenchDbFileName, dummy);
       
   164 	if(err != KErrNone)
       
   165 		{
       
   166 		TheTest.Printf(_L("*** The %S file does not exist, err=%d. Run \"T_BENCH\" test first!\r\n"), &TheBenchDbFileName, err);
       
   167 		TEST2(err, KErrNone);
       
   168 		}
       
   169 	}
       
   170 
       
   171 ///////////////////////////////////////////////////////////////////////////////////////
       
   172 
       
   173 //
       
   174 // Compress the database
       
   175 //
       
   176 void CompressL(const TDesC& aSource, const TDesC& aTarget, TBool aCompress)
       
   177 	{
       
   178 	CFileMan* man = CFileMan::NewL(TheFs);
       
   179 	TInt err = man->Copy(aSource, aTarget);
       
   180 	delete man;
       
   181 	User::LeaveIfError(err);
       
   182 	
       
   183 	User::LeaveIfError(TheFs.SetAtt(aTarget, 0, KEntryAttReadOnly));
       
   184 	CFileStore* store = CFileStore::OpenLC(TheFs, aTarget, EFileRead|EFileWrite);
       
   185 	
       
   186 	TUint32 fc = User::FastCounter();
       
   187 	if(aCompress)
       
   188 		{
       
   189 		RDbStoreDatabase::CompressL(*store, store->Root());
       
   190 		}
       
   191 	else
       
   192 		{
       
   193 		RDbStoreDatabase::DecompressL(*store, store->Root());
       
   194 		}
       
   195 	TUint32 time = CalcTickDiff(fc, User::FastCounter());
       
   196 	PrintFcDiffAsUs(_L(" %d us\r\n"), time);
       
   197 	
       
   198 	store->CompactL();
       
   199 	store->CommitL();
       
   200 	
       
   201 	CleanupStack::PopAndDestroy(store);
       
   202 	}
       
   203 
       
   204 void CheckTableL(RDbDatabase& aDatabase, RDbDatabase& aCopy, const TDesC& aTable)
       
   205 	{
       
   206 	TheTest.Printf(_L("Processing table %S\n"), &aTable);
       
   207 	
       
   208 	TInt err = TheTable1.Open(aDatabase, aTable, RDbRowSet::EReadOnly);
       
   209 	TEST2(err, KErrNone);
       
   210 	
       
   211 	err = TheTable2.Open(aCopy, aTable, RDbRowSet::EReadOnly);
       
   212 	TEST2(err, KErrNone);
       
   213 	
       
   214 	TInt columns = TheTable1.ColCount();
       
   215 	while(TheTable1.NextL())
       
   216 		{
       
   217 		TheTable1.GetL();
       
   218 		TEST(TheTable2.NextL());
       
   219 		TheTable2.GetL();
       
   220 		for(TInt ii=1;ii<=columns;++ii)
       
   221 			{
       
   222 			if(TDbCol::IsLong(TheTable1.ColType(ii)))
       
   223 				{
       
   224 				TInt len = TheTable1.ColSize(ii);
       
   225 				TEST2(len, TheTable2.ColSize(ii));
       
   226 				RDbColReadStream strm1;
       
   227 				strm1.OpenLC(TheTable1, ii);
       
   228 				RDbColReadStream strm2;
       
   229 				strm2.OpenLC(TheTable2, ii);
       
   230 				TBuf8<512> buf1;
       
   231 				TBuf8<512> buf2;
       
   232 				while(len)
       
   233 					{
       
   234 					TInt block = Min(512, len);
       
   235 					strm1.ReadL(buf1, block);
       
   236 					strm2.ReadL(buf2, block);
       
   237 					TEST(buf1 == buf2);
       
   238 					len -= block;
       
   239 					}
       
   240 				CleanupStack::PopAndDestroy(2);
       
   241 				}
       
   242 			else
       
   243 				{
       
   244 				TEST(TheTable1.ColDes8(ii) == TheTable2.ColDes8(ii));
       
   245 				}
       
   246 			}
       
   247 		}
       
   248 	TheTable2.Close();
       
   249 	TheTable1.Close();
       
   250 	}
       
   251 
       
   252 void CheckL(const TDesC& aSource, const TDesC& aTarget)
       
   253 	{
       
   254 	TInt err = TheCompDb.Open(TheFs, aSource, KNullDesC, RDbNamedDatabase::EReadOnly);
       
   255 	TEST2(err, KErrNone);
       
   256 	
       
   257 	err = TheCopyDb.Open(TheFs, aTarget, KNullDesC, RDbNamedDatabase::EReadOnly);
       
   258 	TEST2(err, KErrNone);
       
   259 	
       
   260 	CDbTableNames* tables = TheCompDb.TableNamesL();
       
   261 	for(TInt ii=0;ii<tables->Count();++ii)
       
   262 		{
       
   263 		CheckTableL(TheCompDb, TheCopyDb, (*tables)[ii]);
       
   264 		}
       
   265 	delete tables;
       
   266 	TheCopyDb.Close();
       
   267 	TheCompDb.Close();
       
   268 	}
       
   269 
       
   270 /**
       
   271 @SYMTestCaseID          SYSLIB-DBMS-CT-0593
       
   272 @SYMTestCaseDesc        Database compression tests.
       
   273 @SYMTestPriority        Medium
       
   274 @SYMTestActions         Tests for RDbStoreDatabase::CompressL(),RDbStoreDatabase::DecompressL() functions
       
   275 @SYMTestExpectedResults Test must not fail
       
   276 @SYMREQ                 REQ0000
       
   277 */
       
   278 void Test(const TDesC& aSource, const TDesC& aTarget, TBool aCompress)
       
   279 	{
       
   280 	TRAPD(err, CompressL(aSource, aTarget, aCompress));
       
   281 	TEST2(err, KErrNone);
       
   282 	TheTest.Printf(_L("Checking database"));
       
   283 	TRAP(err, CheckL(aSource, aTarget));
       
   284 	TEST2(err, KErrNone);
       
   285 	}
       
   286 
       
   287 void DoTests()
       
   288 	{
       
   289 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0593 Compressing..."));
       
   290 	Test(TheBenchDbFileName, TheCompressedFileName, ETrue);
       
   291 	
       
   292 	TheTest.Next(_L("Decompressing..."));
       
   293 	Test(TheCompressedFileName, TheDecompressedFileName, EFalse);
       
   294 	}
       
   295 
       
   296 //Usage: "t_comp [<drive letter>:]]"
       
   297 TInt E32Main()
       
   298     {
       
   299 	TheTest.Title();
       
   300 
       
   301 	CTrapCleanup* tc = CTrapCleanup::New();
       
   302 	TheTest(tc != NULL);
       
   303 	
       
   304 	TBuf<256> cmdline;
       
   305 	User::CommandLine(cmdline);
       
   306 
       
   307 	TParse parse;
       
   308 
       
   309 	_LIT(KBenchDbFile, "C:\\DBMS-TST\\T_BENCH.DB");
       
   310 	parse.Set(cmdline, &KBenchDbFile, 0);
       
   311 	TheBenchDbFileName.Copy(parse.FullName());
       
   312 
       
   313 	_LIT(KCompressedFile, "C:\\DBMS-TST\\T_COMP.DB1");
       
   314 	parse.Set(cmdline, &KCompressedFile, 0);
       
   315 	TheCompressedFileName.Copy(parse.FullName());
       
   316 
       
   317 	_LIT(KDecompressedFile, "C:\\DBMS-TST\\T_COMP.DB2");
       
   318 	parse.Set(cmdline, &KDecompressedFile, 0);
       
   319 	TheDecompressedFileName.Copy(parse.FullName());
       
   320 	
       
   321 	__UHEAP_MARK;
       
   322 	
       
   323 	CreateTestEnv();
       
   324 	DoTests();
       
   325 	DestroyTestEnv();
       
   326 
       
   327 	delete tc;
       
   328 
       
   329 	__UHEAP_MARKEND;
       
   330 	
       
   331 	TheTest.End();
       
   332 	TheTest.Close();
       
   333 	
       
   334 	return 0;
       
   335     }