persistentstorage/sql/TEST/t_sqldbconfigfile.cpp
changeset 0 08ec8eefde2f
child 9 667e88a979d7
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2008-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 #include <e32test.h>
       
    17 #include <stdlib.h>
       
    18 #include <bautils.h>
       
    19 #include <hal.h>
       
    20 #include <sqldb.h>
       
    21 #include "sqlite3.h"
       
    22 #include "SqliteSymbian.h"
       
    23 #include "SqlResourceTester.h"
       
    24 
       
    25 /////////////////////////////////////////////////////////////////////////////////////////////////
       
    26 /// This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined! ///
       
    27 /////////////////////////////////////////////////////////////////////////////////////////////////
       
    28 
       
    29 RTest TheTest(_L("t_sqldbconfigfile test"));
       
    30 
       
    31 #ifdef SYSLIBS_TEST	
       
    32 
       
    33 extern TBool IsStatementSupported(const TDesC& aStatementIn, const TDesC& aDbName, TDes& aStatementOut);
       
    34 
       
    35 RFs TheFs;
       
    36 RSqlDatabase TheDb;
       
    37 sqlite3 *TheDbHandle = NULL;
       
    38 
       
    39 _LIT(KTestDir, "c:\\test\\");
       
    40 _LIT(KSqlSrvName, "sqlsrv.exe");
       
    41 
       
    42 enum TConfigParamType {EPrmCacheSize, EPrmPageSize, EPrmDbEncoding};
       
    43 
       
    44 TInt KillProcess(const TDesC& aProcessName);
       
    45 
       
    46 _LIT(KCfgDb1, "c:[1111C1C1]a.db"); // shared, secure db
       
    47 _LIT(KCfgDb2, "c:[1111C1C1]b.db"); // shared, secure db (no config file for it)
       
    48 _LIT(KCfgDb3, "c:\\private\\1111C1C1\\c.db"); // private, secure db
       
    49 _LIT(KCfgDb4, "c:\\test\\d.db"); // public db
       
    50 _LIT(KCfgDb5, "c:[1111C1C1]e.db"); // shared, secure db (config file created before db is created)
       
    51 
       
    52 _LIT(KCfgDb1ConfigFilePath, "c:\\private\\10281e17\\cfg[1111C1C1]a.db.0%d"); // config file version %d for a.db
       
    53 _LIT(KCfgDb3ConfigFileV01Path, "c:\\private\\10281e17\\cfgc.db.01"); // config file v01 for c.db (unsupported)
       
    54 _LIT(KCfgDb4ConfigFileV01Path, "c:\\private\\10281e17\\cfgd.db.01"); // config file v01 for d.db (unsupported)
       
    55 _LIT(KCfgDb5ConfigFileV01Path, "c:\\private\\10281e17\\cfg[1111C1C1]e.db.01"); // config file v01 for e.db
       
    56 _LIT(KCfgDb1CorruptConfigFilePath, "c:\\private\\10281e17\\cfg[1111C1C1]a.db.invalidextension"); // invalid config file name syntax
       
    57 
       
    58 // config file v01 contents for db1 (also tests that upper and lower case statements are both supported)
       
    59 _LIT8(KCfgDb1ConfigFile01Stmts, "CREATE INDEX idx ON table1(i1);CREATE INDEX idx2 ON table1(i2);INSERT INTO table1 (i1,i2,i3) values(5,8,9);DELETE FROM table1;create index multiidx ON TABLE1(i2,i3)");
       
    60 // config file v01 contents for db3 (will not be processed as db3 is not a shared, secure db)
       
    61 _LIT8(KCfgDb3ConfigFile01Stmts, "CREATE INDEX idx ON table3(i1)");
       
    62 // config file v01 contents for db4 (will not be processed as db4 is not a shared, secure db)
       
    63 _LIT8(KCfgDb4ConfigFile01Stmts, "CREATE INDEX idx ON table4(i1)");
       
    64 // config file v01 contents for db5 (will eventually be processed after db5 itself is created)
       
    65 _LIT8(KCfgDb5ConfigFile01Stmts, "CREATE INDEX idx ON table5(i1);\r\n");
       
    66 // config file valid contents (used for v02 and others)
       
    67 _LIT8(KCfgConfigFileValidStmt, "CREATE INDEX newIdx ON table1(i3)  ;"); 
       
    68 // config file v03 empty contents
       
    69 _LIT8(KCfgDb1ConfigFileV03EmptyStmt, ""); 
       
    70 // config file v04 unsupported contents
       
    71 _LIT8(KCfgDb1ConfigFileV04UnsupportedStmt, "DELETE FROM table1"); 
       
    72 // config file v05 only whitespace contents
       
    73 _LIT8(KCfgDb1ConfigFileV05OnlyWhitespaceStmt, " \r\n   \r\n"); 
       
    74 // config file v06 invalid schema contents
       
    75 _LIT8(KCfgDb1ConfigFileV06InvalidSchemaStmt, "CREATE INDEX thisIdx ON table999(i3)"); 
       
    76 // config file v07 unsupported comment style
       
    77 _LIT8(KCfgDb1ConfigFileV07InvalidCommentedStmt, "CREATE INDEX ind1 ON table1(i2) // create an index"); 
       
    78 // config file v08 sequence of different statements
       
    79 _LIT8(KCfgDb1ConfigFileV08SeqStmt, ";  CREATE INDEX IdxFirst ON table1(i3)\r\n;  DELETE FROM table1;INSERT INTO table1 (i1,i2,i3) values(6,7,8);;CREATE INDEX IdxSecond ON table1(i1);");
       
    80 // config file v09 whitespace before and after statement
       
    81 _LIT8(KCfgDb1ConfigFileV09WhitespacePreAndPostStmt, "  CREATE INDEX intIdx ON table1(i1)       "); 
       
    82 // config file v10 valid contents
       
    83 _LIT8(KCfgDb1ConfigFileV10ValidStmt, "CREATE INDEX i3Index ON table1(i3)\n"); 
       
    84 // config file v11 valid contents (also tests that any amount spaces and tabs are allowed between 'CREATE' and 'INDEX')
       
    85 _LIT8(KCfgDb1ConfigFileV11ValidStmt, "CREATE     INDEX i1Index ON table1(i1);\nCREATE	INDEX i2Index ON table1(i2)");
       
    86 // config file v12 invalid stmt plus valid stmt
       
    87 _LIT8(KCfgDb1ConfigFileV12InvalidPlusValidStmt, "CREATE UNIQUE INDEX uniqueIdx ON table1(i1);CREATE INDEX v12Idx ON table1(i2)");
       
    88 // config file v13 supported SQL comment style
       
    89 _LIT8(KCfgDb1ConfigFileV13SQLCommentStmt, "CREATE INDEX v13Idx ON table1(i1) -- this is an SQL comment");
       
    90 // config file v14 supported 'C' comment style
       
    91 _LIT8(KCfgDb1ConfigFileV14CCommentStmt, "CREATE INDEX v14Idx ON table1(i3) /* this is a C comment */;");
       
    92 
       
    93 //KLongDbName1 is "long" enough to allow "-journal" to be added at the end.
       
    94 _LIT(KLongDbName1,  "c:[1111C1C1]a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a1234.db");
       
    95 _LIT(KLongCfgName1, "c:\\private\\10281e17\\cfg[1111C1C1]a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a123456789a1234.db.01");
       
    96 
       
    97 _LIT(KSqlSrvPrivatePath, "\\private\\10281e17\\");
       
    98 _LIT(KGetSettingsSql, "SELECT * FROM symbian_settings WHERE Reserved==%d");
       
    99 _LIT(KResetCollationDllSql, "UPDATE symbian_settings SET CollationDllName='hjagafsff'");
       
   100 _LIT(KGetCollationDllSql, "SELECT CollationDllName FROM symbian_settings");
       
   101 
       
   102 _LIT(KAttachDb1, "Db1");
       
   103 _LIT(KAttachDb2, "Db2");
       
   104 _LIT(KAttachDb5, "Db5");
       
   105 
       
   106 _LIT(KDb1CheckNumRecords, "SELECT * FROM table1");
       
   107 _LIT(KDb2CheckNumRecords, "SELECT * FROM table2");
       
   108 _LIT(KDb3CheckNumRecords, "SELECT * FROM table3");
       
   109 _LIT(KDb4CheckNumRecords, "SELECT * FROM table4");
       
   110 _LIT(KDb5CheckNumRecords, "SELECT * FROM table5");
       
   111 _LIT(KDbCheckNumIndices, "SELECT name FROM sqlite_master WHERE type = 'index'");
       
   112 
       
   113 ///////////////////////////////////////////////////////////////////////////////////////
       
   114 // Destroy functions
       
   115 
       
   116 TInt KillProcess(const TDesC& aProcessName)
       
   117 	{
       
   118 	TFullName name;
       
   119 	//RDebug::Print(_L("Find and kill \"%S\" process.\n"), &aProcessName);
       
   120 	TBuf<64> pattern(aProcessName);
       
   121 	TInt length = pattern.Length();
       
   122 	pattern += _L("*");
       
   123 	TFindProcess procFinder(pattern);
       
   124 
       
   125 	while (procFinder.Next(name) == KErrNone)
       
   126 		{
       
   127 		if (name.Length() > length)
       
   128 			{//If found name is a string containing aProcessName string.
       
   129 			TChar c(name[length]);
       
   130 			if (c.IsAlphaDigit() ||
       
   131 				c == TChar('_') ||
       
   132 				c == TChar('-'))
       
   133 				{
       
   134 				// If the found name is other valid application name
       
   135 				// starting with aProcessName string.
       
   136 				//RDebug::Print(_L(":: Process name: \"%S\".\n"), &name);
       
   137 				continue;
       
   138 				}
       
   139 			}
       
   140 		RProcess proc;
       
   141 		if (proc.Open(name) == KErrNone)
       
   142 			{
       
   143 			proc.Kill(0);
       
   144 			//RDebug::Print(_L("\"%S\" process killed.\n"), &name);
       
   145 			}
       
   146 		proc.Close();
       
   147 		}
       
   148 	return KErrNone;
       
   149 	}
       
   150 
       
   151 void DeleteCfgFilesAndDbs()
       
   152 	{
       
   153  	(void)RSqlDatabase::Delete(KLongDbName1);
       
   154  	(void)RSqlDatabase::Delete(KCfgDb1);
       
   155  	(void)RSqlDatabase::Delete(KCfgDb2);	
       
   156  	(void)RSqlDatabase::Delete(KCfgDb3);
       
   157  	(void)RSqlDatabase::Delete(KCfgDb4);
       
   158  	(void)RSqlDatabase::Delete(KCfgDb5);
       
   159  	(void)TheFs.Delete(KLongCfgName1);
       
   160  	(void)TheFs.Delete(KCfgDb3ConfigFileV01Path);
       
   161  	(void)TheFs.Delete(KCfgDb4ConfigFileV01Path);
       
   162  	(void)TheFs.Delete(KCfgDb5ConfigFileV01Path);
       
   163  	CFileMan* fileMan = 0;	
       
   164  	TRAPD(err, fileMan = CFileMan::NewL(TheFs));
       
   165  	if(KErrNone == err)
       
   166  		{
       
   167  		(void)fileMan->Delete(_L("c:\\private\\10281e17\\cfg[1111C1C1]a.db.*"));
       
   168 		delete fileMan;			
       
   169  		}
       
   170   	}
       
   171 
       
   172 void DestroyTestEnv()
       
   173 	{
       
   174 	if(TheDbHandle)
       
   175 		{
       
   176 		sqlite3_close(TheDbHandle);	
       
   177 		TheDbHandle = NULL;
       
   178 		}
       
   179 	TheDb.Close();
       
   180 	(void)KillProcess(KSqlSrvName);
       
   181 	DeleteCfgFilesAndDbs();
       
   182 	TheFs.Close();
       
   183 	}
       
   184 	
       
   185 ///////////////////////////////////////////////////////////////////////////////////////
       
   186 // Test macros and functions
       
   187 
       
   188 void Check(TInt aValue, TInt aLine)
       
   189 	{
       
   190 	if(!aValue)
       
   191 		{
       
   192 		DestroyTestEnv();
       
   193 		TheTest(EFalse, aLine);
       
   194 		}
       
   195 	}
       
   196 void Check(TInt aValue, TInt aExpected, TInt aLine)
       
   197 	{
       
   198 	if(aValue != aExpected)
       
   199 		{
       
   200 		DestroyTestEnv();
       
   201 		TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
   202 		TheTest(EFalse, aLine);
       
   203 		}
       
   204 	}
       
   205 #define TEST(arg) ::Check((arg), __LINE__)
       
   206 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
   207 
       
   208 // OOM test functions
       
   209 
       
   210 static TInt TheHandleCount1;
       
   211 static TInt TheHandleCount2;
       
   212 static TInt TheAllocatedCellsCount;
       
   213 
       
   214 void MarkHandles()
       
   215 	{
       
   216 	RThread().HandleCount(TheHandleCount1, TheHandleCount2);
       
   217 	}
       
   218 
       
   219 void CheckHandles()
       
   220 	{
       
   221 	TInt endHandleCount1;
       
   222 	TInt endHandleCount2;
       
   223 
       
   224 	RThread().HandleCount(endHandleCount1, endHandleCount2);
       
   225 
       
   226 	TEST(TheHandleCount1 == endHandleCount1);
       
   227 	TEST(TheHandleCount2 == endHandleCount2);
       
   228 	}
       
   229 
       
   230 void MarkAllocatedCells()
       
   231 	{
       
   232 	TheAllocatedCellsCount = User::CountAllocCells();
       
   233 	}
       
   234 
       
   235 void CheckAllocatedCells()
       
   236 	{
       
   237 	TInt allocatedCellsCount = User::CountAllocCells();
       
   238 	TEST(allocatedCellsCount == TheAllocatedCellsCount);
       
   239 	}
       
   240 
       
   241 ///////////////////////////////////////////////////////////////////////////////////////
       
   242 // Set up functions
       
   243 
       
   244 TInt DoCreateSecurityPolicy(RSqlSecurityPolicy& securityPolicy)
       
   245 	{
       
   246 	const TSecurityPolicy KDefaultPolicy(TSecurityPolicy::EAlwaysPass);
       
   247 	if((KErrNone != securityPolicy.Create(KDefaultPolicy))
       
   248 	   ||
       
   249 	   (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::ESchemaPolicy, KDefaultPolicy))
       
   250 	   ||
       
   251 	   (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EWritePolicy, KDefaultPolicy))
       
   252 	   ||
       
   253 	   (KErrNone != securityPolicy.SetDbPolicy(RSqlSecurityPolicy::EReadPolicy, KDefaultPolicy)))
       
   254 		{
       
   255 		return KErrGeneral;
       
   256 		}
       
   257 		
       
   258 	return KErrNone;
       
   259 	}
       
   260 	
       
   261 void CreateCfgFiles()
       
   262 	{
       
   263  	// Create v01 of the test config files
       
   264  	
       
   265  	RFile file;
       
   266 	TFileName fileName;
       
   267 	TInt v1 = 1;
       
   268 	fileName.Format(KCfgDb1ConfigFilePath(), v1);
       
   269 	TInt err = file.Create(TheFs, fileName, EFileRead | EFileWrite);
       
   270 	TEST2(err, KErrNone);
       
   271 	TPtrC8 pDb1((const TUint8*)KCfgDb1ConfigFile01Stmts().Ptr(), KCfgDb1ConfigFile01Stmts().Length());
       
   272 	err = file.Write(pDb1);	
       
   273 	file.Close();	
       
   274 	TEST2(err, KErrNone);
       
   275 	
       
   276 	fileName.Copy(KCfgDb3ConfigFileV01Path);
       
   277 	err = file.Create(TheFs, fileName, EFileRead | EFileWrite);
       
   278 	TEST2(err, KErrNone);
       
   279 	TPtrC8 pDb3((const TUint8*)KCfgDb3ConfigFile01Stmts().Ptr(), KCfgDb3ConfigFile01Stmts().Length());
       
   280 	err = file.Write(pDb3);	
       
   281 	file.Close();	
       
   282 	TEST2(err, KErrNone);	
       
   283 	
       
   284 	fileName.Copy(KCfgDb4ConfigFileV01Path);
       
   285 	err = file.Create(TheFs, fileName, EFileRead | EFileWrite);
       
   286 	TEST2(err, KErrNone);
       
   287 	TPtrC8 pDb4((const TUint8*)KCfgDb4ConfigFile01Stmts().Ptr(), KCfgDb4ConfigFile01Stmts().Length());
       
   288 	err = file.Write(pDb4);	
       
   289 	file.Close();	
       
   290 	TEST2(err, KErrNone);
       
   291 	
       
   292 	fileName.Copy(KCfgDb5ConfigFileV01Path); // create the config file for Db5 before the database has been created
       
   293 	err = file.Create(TheFs, fileName, EFileRead | EFileWrite);
       
   294 	TEST2(err, KErrNone);
       
   295 	TPtrC8 pDb5((const TUint8*)KCfgDb5ConfigFile01Stmts().Ptr(), KCfgDb5ConfigFile01Stmts().Length());
       
   296 	err = file.Write(pDb5);	
       
   297 	file.Close();	
       
   298 	TEST2(err, KErrNone);	
       
   299 	}
       
   300 
       
   301 void CreateCfgDbs()
       
   302 	{
       
   303 	// Create the test databases
       
   304 	
       
   305  	TBuf<100> sql;
       
   306  		
       
   307  	RSqlSecurityPolicy securityPolicy;
       
   308  	TInt err = DoCreateSecurityPolicy(securityPolicy);
       
   309  	TEST2(err, KErrNone);
       
   310  	
       
   311  	err = TheDb.Create(KCfgDb1, securityPolicy);
       
   312  	TEST2(err, KErrNone);
       
   313  	sql.Copy(_L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
   314  	err = TheDb.Exec(sql);
       
   315  	TEST(err >= 0);
       
   316  	sql.Copy(_L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"));
       
   317  	err = TheDb.Exec(sql);
       
   318  	TEST(err == 1);
       
   319  	TheDb.Close();
       
   320  	
       
   321  	err = TheDb.Create(KCfgDb2, securityPolicy);
       
   322  	TEST2(err, KErrNone);
       
   323  	sql.Copy(_L("CREATE TABLE table2(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
   324  	err = TheDb.Exec(sql);
       
   325  	TEST(err >= 0);
       
   326  	sql.Copy(_L("INSERT INTO table2 (i1,i2,i3) values(4,5,6)"));
       
   327  	err = TheDb.Exec(sql);
       
   328  	TEST(err == 1);
       
   329  	TheDb.Close();
       
   330  	
       
   331  	securityPolicy.Close();
       
   332  
       
   333  	err = TheDb.Create(KCfgDb3);
       
   334  	TEST2(err, KErrNone);
       
   335  	sql.Copy(_L("CREATE TABLE table3(i1 INTEGER, i2 INTEGER)"));
       
   336  	err = TheDb.Exec(sql);
       
   337  	TEST(err >= 0);
       
   338  	sql.Copy(_L("INSERT INTO table3 (i1,i2) values(7,8)"));
       
   339  	err = TheDb.Exec(sql);
       
   340  	TEST(err == 1);
       
   341  	TheDb.Close();	
       
   342  
       
   343  	err = TheDb.Create(KCfgDb4);
       
   344  	TEST2(err, KErrNone);
       
   345  	sql.Copy(_L("CREATE TABLE table4(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
   346  	err = TheDb.Exec(sql);
       
   347  	TEST(err >= 0);
       
   348  	sql.Copy(_L("INSERT INTO table4 (i1,i2,i3) values(9,10,11)"));
       
   349  	err = TheDb.Exec(sql);
       
   350  	TEST(err == 1);
       
   351  	TheDb.Close();
       
   352  	}
       
   353 
       
   354 void CreateCfgFilesAndDbs()
       
   355 	{
       
   356 	CreateCfgFiles();
       
   357 	CreateCfgDbs();
       
   358 	
       
   359 	// Must now kill the SQL Server so that the config files 
       
   360 	// created above are found and processed when it restarts
       
   361 	(void)KillProcess(KSqlSrvName);
       
   362  	}
       
   363  	
       
   364  void CreateDb5()
       
   365 	{
       
   366 	// Create the Db5 test database (a config file for it already exists)
       
   367 	
       
   368  	TBuf<100> sql;
       
   369  		
       
   370  	RSqlSecurityPolicy securityPolicy;
       
   371  	TInt err = DoCreateSecurityPolicy(securityPolicy);
       
   372  	TEST2(err, KErrNone);
       
   373  	
       
   374  	err = TheDb.Create(KCfgDb5, securityPolicy);
       
   375  	TEST2(err, KErrNone);
       
   376  	sql.Copy(_L("CREATE TABLE table5(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
   377  	err = TheDb.Exec(sql);
       
   378  	TEST(err >= 0);
       
   379  	sql.Copy(_L("INSERT INTO table5 (i1,i2,i3) values(1,2,3)"));
       
   380  	err = TheDb.Exec(sql);
       
   381  	TEST(err == 1);
       
   382  	
       
   383  	TheDb.Close();
       
   384  	securityPolicy.Close();
       
   385 	}
       
   386 
       
   387 void SetupTestEnv()
       
   388     {
       
   389 	TInt err = TheFs.Connect();
       
   390 	TEST2(err, KErrNone);
       
   391 
       
   392 	err = TheFs.MkDir(KTestDir);
       
   393 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   394 
       
   395 	err = TheFs.CreatePrivatePath(EDriveC);
       
   396 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   397 
       
   398 	// Create the cfg dbs and config files
       
   399  	DeleteCfgFilesAndDbs(); // just incase any previous files are lingering
       
   400  	CreateCfgFilesAndDbs();
       
   401 	}
       
   402 
       
   403 ///////////////////////////////////////////////////////////////////////////////////////
       
   404 //
       
   405 TInt CalcTimeMs(TUint32 aStartTicks, TUint32 aEndTicks)
       
   406 	{
       
   407 	static TInt freq = 0;
       
   408 	if(freq == 0)
       
   409 		{
       
   410 		TEST2(HAL::Get(HAL::EFastCounterFrequency, freq), KErrNone);
       
   411 		}
       
   412 	TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks;
       
   413 	if(diffTicks < 0)
       
   414 		{
       
   415 		diffTicks = KMaxTUint32 + diffTicks + 1;
       
   416 		}
       
   417 	const TInt KMicroSecIn1Sec = 1000000;
       
   418 	TInt32 us = (diffTicks * KMicroSecIn1Sec) / freq;
       
   419 	return us / 1000;
       
   420 	}
       
   421 
       
   422 ///////////////////////////////////////////////////////////////////////////////////////
       
   423 // Config file replacement functions
       
   424 
       
   425 void UpgradeDbConfigFile(const TInt aCurrentVersion)
       
   426 	{
       
   427 	(void)KillProcess(KSqlSrvName);
       
   428 	TFileName oldFile;
       
   429 	oldFile.Format(KCfgDb1ConfigFilePath(), aCurrentVersion);
       
   430 	TInt err = TheFs.Delete(oldFile);
       
   431 	TEST2(err, KErrNone);
       
   432 	RFile file;
       
   433 	TFileName newFile;
       
   434 	TInt newVersion = aCurrentVersion+1;
       
   435 	newFile.Format(KCfgDb1ConfigFilePath(), newVersion);
       
   436 	err = file.Create(TheFs, newFile, EFileRead | EFileWrite);
       
   437 	TEST2(err, KErrNone);
       
   438 	
       
   439 	switch(newVersion)
       
   440 		{
       
   441 			case 2:
       
   442 				{
       
   443 				TPtrC8 p((const TUint8*)KCfgConfigFileValidStmt().Ptr(), KCfgConfigFileValidStmt().Length());
       
   444 				err = file.Write(p);
       
   445 				break;
       
   446 				}
       
   447 			case 3:
       
   448 				{
       
   449 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV03EmptyStmt().Ptr(), KCfgDb1ConfigFileV03EmptyStmt().Length());
       
   450 				err = file.Write(p);
       
   451 				break;
       
   452 				}
       
   453 			case 4:
       
   454 				{
       
   455 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV04UnsupportedStmt().Ptr(), KCfgDb1ConfigFileV04UnsupportedStmt().Length());
       
   456 				err = file.Write(p);
       
   457 				break;	
       
   458 				}
       
   459 			case 5:
       
   460 				{
       
   461 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV05OnlyWhitespaceStmt().Ptr(), KCfgDb1ConfigFileV05OnlyWhitespaceStmt().Length());
       
   462 				err = file.Write(p);
       
   463 				break;
       
   464 				}	
       
   465 			case 6:
       
   466 				{
       
   467 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV06InvalidSchemaStmt().Ptr(), KCfgDb1ConfigFileV06InvalidSchemaStmt().Length());
       
   468 				err = file.Write(p);
       
   469 				break;
       
   470 				}
       
   471 			case 7:
       
   472 				{
       
   473 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV07InvalidCommentedStmt().Ptr(), KCfgDb1ConfigFileV07InvalidCommentedStmt().Length());
       
   474 				err = file.Write(p);	
       
   475 				break;
       
   476 				}
       
   477 			case 8:
       
   478 				{
       
   479 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV08SeqStmt().Ptr(), KCfgDb1ConfigFileV08SeqStmt().Length());
       
   480 				err = file.Write(p);	
       
   481 				break;
       
   482 				}
       
   483 			case 9:
       
   484 				{
       
   485 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV09WhitespacePreAndPostStmt().Ptr(), KCfgDb1ConfigFileV09WhitespacePreAndPostStmt().Length());
       
   486 				err = file.Write(p);	
       
   487 				break;
       
   488 				}
       
   489 			case 12:
       
   490 				{
       
   491 				// also delete version 10 of file
       
   492 				oldFile.Format(KCfgDb1ConfigFilePath(), 10);
       
   493 				err = TheFs.Delete(oldFile);
       
   494 				TEST2(err, KErrNone);	
       
   495 				
       
   496 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV12InvalidPlusValidStmt().Ptr(), KCfgDb1ConfigFileV12InvalidPlusValidStmt().Length());
       
   497 				err = file.Write(p);
       
   498 				break;
       
   499 				}
       
   500 			case 13:
       
   501 				{
       
   502 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV13SQLCommentStmt().Ptr(), KCfgDb1ConfigFileV13SQLCommentStmt().Length());
       
   503 				err = file.Write(p);	
       
   504 				break;
       
   505 				}
       
   506 			case 14:
       
   507 				{
       
   508 				TPtrC8 p((const TUint8*)KCfgDb1ConfigFileV14CCommentStmt().Ptr(), KCfgDb1ConfigFileV14CCommentStmt().Length());
       
   509 				err = file.Write(p);	
       
   510 				break;
       
   511 				}
       
   512 			default:
       
   513 				{
       
   514 				err = KErrArgument;
       
   515 				break;
       
   516 				}		
       
   517 		}
       
   518 	file.Close();
       
   519 	TEST2(err, KErrNone);
       
   520 	}	
       
   521 	
       
   522 void DowngradeDbConfigFile(const TInt aCurrentVersion)
       
   523 	{
       
   524 	(void)KillProcess(KSqlSrvName);
       
   525 	TFileName oldFile;
       
   526 	oldFile.Format(KCfgDb1ConfigFilePath(), aCurrentVersion);
       
   527 	TInt err = TheFs.Delete(oldFile);
       
   528 	TEST2(err, KErrNone);
       
   529 	RFile file;
       
   530 	TFileName newFile;
       
   531 	TInt previousVersion = aCurrentVersion-1;
       
   532 	TEST(previousVersion > 0);
       
   533 	newFile.Format(KCfgDb1ConfigFilePath(), previousVersion);
       
   534 	err = file.Create(TheFs, newFile, EFileRead | EFileWrite);
       
   535 	TEST2(err, KErrNone);
       
   536 	TPtrC8 p((const TUint8*)KCfgConfigFileValidStmt().Ptr(), KCfgConfigFileValidStmt().Length());
       
   537 	err = file.Write(p);
       
   538 	file.Close();
       
   539 	TEST2(err, KErrNone);
       
   540 	}
       
   541 	
       
   542 void CreateCorruptDbConfigFile(const TInt aCurrentVersion)
       
   543 	{
       
   544 	(void)KillProcess(KSqlSrvName);
       
   545 	TFileName oldFile;
       
   546 	oldFile.Format(KCfgDb1ConfigFilePath(), aCurrentVersion);
       
   547 	TInt err = TheFs.Delete(oldFile);
       
   548 	TEST2(err, KErrNone);
       
   549 	RFile file;
       
   550 	err = file.Create(TheFs, KCfgDb1CorruptConfigFilePath(), EFileRead | EFileWrite);
       
   551 	TEST2(err, KErrNone);
       
   552 	TPtrC8 p((const TUint8*)KCfgConfigFileValidStmt().Ptr(), KCfgConfigFileValidStmt().Length());
       
   553 	err = file.Write(p);
       
   554 	file.Close();
       
   555 	TEST2(err, KErrNone);
       
   556 	}	
       
   557 	
       
   558 void CreateTwoVersionsOfConfigFile()
       
   559 	{
       
   560 	(void)KillProcess(KSqlSrvName);
       
   561 	TInt err = TheFs.Delete(KCfgDb1CorruptConfigFilePath);
       
   562 	TEST2(err, KErrNone);
       
   563 	RFile file;
       
   564 	TFileName newFile;
       
   565 	TInt nextVersion = 10;
       
   566 	newFile.Format(KCfgDb1ConfigFilePath(), nextVersion);
       
   567 	err = file.Create(TheFs, newFile, EFileRead | EFileWrite);
       
   568 	TEST2(err, KErrNone);
       
   569 	TPtrC8 p10((const TUint8*)KCfgDb1ConfigFileV10ValidStmt().Ptr(), KCfgDb1ConfigFileV10ValidStmt().Length());
       
   570 	err = file.Write(p10);
       
   571 	file.Close();
       
   572 	TEST2(err, KErrNone);
       
   573 	++nextVersion;
       
   574 	newFile.Format(KCfgDb1ConfigFilePath(), nextVersion);
       
   575 	err = file.Create(TheFs, newFile, EFileRead | EFileWrite);
       
   576 	TEST2(err, KErrNone);
       
   577 	TPtrC8 p11((const TUint8*)KCfgDb1ConfigFileV11ValidStmt().Ptr(), KCfgDb1ConfigFileV11ValidStmt().Length());
       
   578 	err = file.Write(p11);
       
   579 	file.Close();
       
   580 	TEST2(err, KErrNone);	
       
   581 	}
       
   582  
       
   583 ///////////////////////////////////////////////////////////////////////////////////////
       
   584 // DoDbCfgTests() functions
       
   585 
       
   586 TBool GuessSystemSettingsTable(const TDesC& aDbName, TInt aVersion)
       
   587 	{
       
   588 	// Note: We have to use SQLite directly to access the settings
       
   589 	// table as the SQL Server denies permission to access this table
       
   590 	// as it is in a shared, secure database
       
   591 	
       
   592 	TBool guessIsCorrect = EFalse;
       
   593 	
       
   594 	TParse parse;
       
   595 	parse.Set(aDbName, &KSqlSrvPrivatePath, 0);
       
   596 	
       
   597 	TBuf8<KMaxFileName + 1> dbFileName;
       
   598 	dbFileName.Copy(parse.FullName());
       
   599 	
       
   600 	TheDbHandle = NULL;
       
   601 	TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &TheDbHandle);
       
   602 	TEST2(rc, SQLITE_OK);
       
   603 	
       
   604 	TBuf<100> queryBuf;
       
   605 	queryBuf.Format(KGetSettingsSql(), aVersion);	
       
   606 	
       
   607 	sqlite3_stmt* stmtHandle = NULL;
       
   608 	const void* stmtTailZ = NULL;
       
   609 	rc = sqlite3_prepare16_v2(TheDbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
       
   610 	TEST2(rc, SQLITE_OK);
       
   611 	
       
   612 	rc = sqlite3_step(stmtHandle);
       
   613 	if(SQLITE_ROW == rc)
       
   614 		{
       
   615 		guessIsCorrect = ETrue;
       
   616 		rc = sqlite3_step(stmtHandle);
       
   617 		TEST2(rc, SQLITE_DONE);
       
   618 		}
       
   619 	
       
   620 	sqlite3_finalize(stmtHandle);
       
   621 	sqlite3_close(TheDbHandle);
       
   622 	TheDbHandle = NULL;
       
   623 	
       
   624 	return guessIsCorrect;
       
   625 	}
       
   626 
       
   627 void CheckSystemSettingsTable(const TDesC& aDbName, TInt aVersion)
       
   628 	{
       
   629 	// Note: We have to use SQLite directly to access the settings
       
   630 	// table as the SQL Server denies permission to access this table
       
   631 	// as it is in a shared, secure database
       
   632 	
       
   633 	TParse parse;
       
   634 	parse.Set(aDbName, &KSqlSrvPrivatePath, 0);
       
   635 	
       
   636 	TBuf8<KMaxFileName + 1> dbFileName;
       
   637 	dbFileName.Copy(parse.FullName());
       
   638 	
       
   639 	sqlite3 *dbHandle = NULL;
       
   640 	TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
       
   641 	TEST2(rc, SQLITE_OK);
       
   642 	
       
   643 	TBuf<100> queryBuf;
       
   644 	queryBuf.Format(KGetSettingsSql(), aVersion);	
       
   645 	
       
   646 	sqlite3_stmt* stmtHandle = NULL;
       
   647 	const void* stmtTailZ = NULL;
       
   648 	rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
       
   649 	TEST2(rc, SQLITE_OK);
       
   650 	
       
   651 	rc = sqlite3_step(stmtHandle);
       
   652 	TEST2(rc, SQLITE_ROW);
       
   653 	
       
   654 	rc = sqlite3_step(stmtHandle);
       
   655 	TEST2(rc, SQLITE_DONE);
       
   656 	
       
   657 	sqlite3_finalize(stmtHandle);
       
   658 	sqlite3_close(dbHandle);
       
   659 	}
       
   660 
       
   661 void CheckNumberRecordsL(const TDesC& aStmt)
       
   662 	{
       
   663 	// There should always be only 1 record in the table
       
   664 	// in each database as INSERT and DELETE statements are
       
   665 	// not supported in the config files
       
   666 	
       
   667 	// Prepare stmt
       
   668 	RSqlStatement stmt;
       
   669 	stmt.PrepareL(TheDb, aStmt);
       
   670 	
       
   671 	// Get each row
       
   672 	TUint numRows = 0;
       
   673 	TInt err = stmt.Next();
       
   674 	while(KSqlAtRow == err)
       
   675 		{
       
   676 		numRows++;
       
   677 		err = stmt.Next();
       
   678 		}
       
   679 
       
   680 	if (KSqlAtEnd != err)
       
   681 		{
       
   682 		User::Leave(KErrCorrupt);
       
   683 		}
       
   684 		
       
   685 	if (numRows != 1)
       
   686 		{
       
   687 		User::Leave(KErrArgument);
       
   688 		}
       
   689 
       
   690 	// Close stmt
       
   691 	stmt.Close();	
       
   692 	}
       
   693 	
       
   694 TInt NumberIndicesExpectedInDb1(const TInt aExpectedStoredVersion)
       
   695 	{
       
   696 	TInt numIndices = -1;
       
   697 	
       
   698 	switch(aExpectedStoredVersion)
       
   699 		{
       
   700      	// Only files 01 - 04, 09 and 11 will be successfully processed and so stored in the settings table
       
   701 		case 1:
       
   702 			{
       
   703 			numIndices = 3; // 3 indices should be added to db1 based on config file 01
       
   704 			break;
       
   705 			}
       
   706 		case 2:
       
   707 			{
       
   708 			numIndices = 4; // 1 more index should be added to db1 based on config file 02
       
   709 			break;
       
   710 			}
       
   711 		case 3:
       
   712 		case 4:
       
   713 		case 5:
       
   714 		case 6:
       
   715 		case 7:
       
   716 			{
       
   717 			numIndices = 4; // no more indices should be added to db1 based on config file 03 - 07
       
   718 			break;
       
   719 			}
       
   720 		case 8:
       
   721 			{
       
   722 			numIndices = 6; // 2 more indices should be added to db1 based on config file 08
       
   723 			break;
       
   724 			}
       
   725 		case 9:
       
   726 			{
       
   727 			numIndices = 7; // 1 more index should be added to db1 based on config file 09
       
   728 			break;
       
   729 			}
       
   730 		case 11:
       
   731 			{
       
   732 			numIndices = 9; // 2 more indices should be added to db1 based on config file 11
       
   733 			break;
       
   734 			}	
       
   735 		case 12:
       
   736 			{
       
   737 			numIndices = 10; // 1 more index should be added to db1 based on config file 12
       
   738 			break;
       
   739 			}
       
   740 		case 13:
       
   741 			{
       
   742 			numIndices = 11; // 1 more index should be added to db1 based on config file 13
       
   743 			break;
       
   744 			}	
       
   745 		case 14:
       
   746 			{
       
   747 			numIndices = 12; // 1 more index should be added to db1 based on config file 14
       
   748 			break;
       
   749 			}		
       
   750 		}
       
   751 		
       
   752 	return numIndices;	
       
   753 	}
       
   754 
       
   755 void CheckNumberIndicesL(const TInt aNumIndicesExpected)
       
   756 	{
       
   757 	// Prepare stmt
       
   758 	RSqlStatement stmt;
       
   759 	stmt.PrepareL(TheDb, KDbCheckNumIndices);
       
   760 	
       
   761 	// Get each entry of type 'index' in the 'sqlite_master' table
       
   762 	TUint numEntries = 0;
       
   763 	TInt err = stmt.Next();
       
   764 	while(KSqlAtRow == err)
       
   765 		{
       
   766 		numEntries++;
       
   767 		err = stmt.Next();
       
   768 		}
       
   769 
       
   770 	if (KSqlAtEnd != err)
       
   771 		{
       
   772 		User::Leave(KErrCorrupt);
       
   773 		}
       
   774 		
       
   775 	if (numEntries != aNumIndicesExpected)
       
   776 		{
       
   777 		User::Leave(KErrArgument);
       
   778 		}
       
   779 
       
   780 	// Close stmt
       
   781 	stmt.Close();	
       
   782 	}
       
   783 
       
   784 void DoCfgOpenTests(TInt aExpectedStoredVersion = 1)
       
   785 	{	
       
   786 	// Open a shared, secure database - config ops should be applied on it
       
   787 	TheTest.Printf(_L("===CfgOpen: Open shared, secure database\r\n"));
       
   788 	TInt err = TheDb.Open(KCfgDb1);
       
   789 	TEST2(err, KErrNone);
       
   790 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords)); // there should still be only 1 record in the table
       
   791 	TEST2(err, KErrNone);
       
   792 	TRAP(err, CheckNumberIndicesL(NumberIndicesExpectedInDb1(aExpectedStoredVersion))); // there should now be 3 indices in the table
       
   793 	TEST2(err, KErrNone);
       
   794 	TheDb.Close();
       
   795 	CheckSystemSettingsTable(KCfgDb1, aExpectedStoredVersion); // check that the ops in the specified config file have been applied
       
   796 		
       
   797 	// Open again the same shared, secure database - no config should occur (it has already been done)
       
   798 	TheTest.Printf(_L("===CfgOpen: Open shared, secure database again\r\n"));
       
   799 	err = TheDb.Open(KCfgDb1);
       
   800 	TEST2(err, KErrNone);
       
   801 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords)); 
       
   802 	TEST2(err, KErrNone);
       
   803 	TRAP(err, CheckNumberIndicesL(NumberIndicesExpectedInDb1(aExpectedStoredVersion)));
       
   804 	TEST2(err, KErrNone);
       
   805 	TheDb.Close();
       
   806 	CheckSystemSettingsTable(KCfgDb1, aExpectedStoredVersion);
       
   807 	
       
   808 	// Open a shared, secure database - no config should occur (there is no config file for this database)
       
   809 	TheTest.Printf(_L("===CfgOpen: Open shared, secure database (that has no config file)\r\n"));
       
   810 	err = TheDb.Open(KCfgDb2);
       
   811 	TEST2(err, KErrNone);
       
   812 	TRAP(err, CheckNumberRecordsL(KDb2CheckNumRecords));
       
   813 	TEST2(err, KErrNone);
       
   814 	TRAP(err, CheckNumberIndicesL(0)); 
       
   815 	TEST2(err, KErrNone);
       
   816 	TheDb.Close();
       
   817 	CheckSystemSettingsTable(KCfgDb2, 0);
       
   818 	
       
   819 	// Open a private, secure database - no config should occur
       
   820 	TheTest.Printf(_L("===CfgOpen: Open private, secure database\r\n"));
       
   821 	err = TheDb.Open(KCfgDb3);
       
   822 	TEST2(err, KErrNone);
       
   823 	TRAP(err, CheckNumberRecordsL(KDb3CheckNumRecords));
       
   824 	TEST2(err, KErrNone);
       
   825 	TRAP(err, CheckNumberIndicesL(0)); 
       
   826 	TEST2(err, KErrNone);
       
   827 	TheDb.Close();
       
   828 	CheckSystemSettingsTable(KCfgDb3, 0);
       
   829 	
       
   830 	// Open a public database - no config should occur
       
   831 	TheTest.Printf(_L("===CfgOpen: Open public database\r\n"));
       
   832 	err = TheDb.Open(KCfgDb4);
       
   833 	TEST2(err, KErrNone);
       
   834 	TRAP(err, CheckNumberRecordsL(KDb4CheckNumRecords));
       
   835 	TEST2(err, KErrNone);
       
   836 	TRAP(err, CheckNumberIndicesL(0)); 
       
   837 	TEST2(err, KErrNone);
       
   838 	TheDb.Close();
       
   839 	CheckSystemSettingsTable(KCfgDb4, 0);
       
   840 	}
       
   841 	
       
   842 void DoUpgradedCfgOpenTest()
       
   843 	{
       
   844 	// Upgrade the config file for KCfgDb1, i.e. replace v1 file with v2 file
       
   845 	UpgradeDbConfigFile(1);
       
   846 	DoCfgOpenTests(2);	
       
   847 	}
       
   848 
       
   849 void DoBadCfgOpenTests()
       
   850 	{
       
   851 	// Test an empty config file
       
   852 	UpgradeDbConfigFile(2); // the current file version is 02, replace it with 03
       
   853 	DoCfgOpenTests(3); // version 03 will be successfully processed and stored in the settings table
       
   854 	
       
   855 	// Test a config file with unsupported operations (these will be ignored)
       
   856 	UpgradeDbConfigFile(3); // the current file version is 03, replace it with 04
       
   857 	DoCfgOpenTests(4); // version 04 will be successfully processed (the unsupported operations are ignored) and stored in the settings table
       
   858 
       
   859 	// Test a config file with only whitespace in it
       
   860 	UpgradeDbConfigFile(4); // the current file version is 04, replace it with 05
       
   861 	DoCfgOpenTests(5); // version 05 will be successfully processed (the whitespace is ignored) and stored in the settings table
       
   862 
       
   863 	// Test a config file with operations on an invalid table
       
   864 	UpgradeDbConfigFile(5); // the current file version is 05, replace it with 06
       
   865 	DoCfgOpenTests(6); // version 06 will be successfully processed (the failed-to-execute operation will be ignored) and stored in the settings table
       
   866 
       
   867 	// Test a config file that contains an invalid comment style
       
   868 	UpgradeDbConfigFile(6); // the current file version is 06, replace it with 07
       
   869 	DoCfgOpenTests(7); // version 07 will be successfully processed (the line with invalid comment syntax will be ignored) and stored in the settings table
       
   870 
       
   871 	// Test a config file that contains a sequence of statements as one statement (this is currently unsupported)
       
   872 	UpgradeDbConfigFile(7); // the current file version is 07, replace it with 08
       
   873 	DoCfgOpenTests(8); // version 08 will be successfully processed (the line with a sequence of statements is ignored) and stored in the settings table	
       
   874 
       
   875 	// Test a config file that contains whitespace before and after the SQL statement
       
   876 	UpgradeDbConfigFile(8); // the current file version is 08, replace it with 09
       
   877 	DoCfgOpenTests(9); // version 09 will be successfully processed and stored in the settings table	
       
   878 
       
   879 	// Test a config file that has a lower extension number
       
   880 	DowngradeDbConfigFile(9); // the current file version is 09, replace it with 08
       
   881 	DoCfgOpenTests(9); // version 08 will NOT be processed (as it is a lower version than that stored), and 09 will remain stored in the settings table
       
   882 
       
   883 	// Test a config file that has an invalid extension
       
   884 	CreateCorruptDbConfigFile(8); // the current file version is 08, replace it with a file with an invalid extension
       
   885 	DoCfgOpenTests(9); // the invalid file will NOT be processed, and 09 will remain stored in the settings table			
       
   886 	
       
   887 	// Test two versions of the config file (two versions should not be present at the same time)
       
   888 	CreateTwoVersionsOfConfigFile(); // the current file has an invalid extension, delete it and create version 10 and version 11
       
   889 	DoCfgOpenTests(11); // only version 11 will be processed (as it is the highest version), and 11 will be stored in the settings table
       
   890 	
       
   891 	// Test a config file that contains an invalid statement and a valid statement
       
   892 	UpgradeDbConfigFile(11); // the current file versions are 10 and 11, replace them with 12
       
   893 	DoCfgOpenTests(12); // version 12 will be successfully processed (the invalid statement will be ignored and the valid statement executed) and stored in the settings table
       
   894 	
       
   895 	// Test a config file that contains a SQL style comment
       
   896 	UpgradeDbConfigFile(12); // the current file version is 12, replace it with 13
       
   897 	DoCfgOpenTests(13); // version 13 will be successfully processed (the SQL style comment will be ignored) and stored in the settings table
       
   898 	
       
   899 	// Test a config file that contains a 'C' style comment
       
   900 	UpgradeDbConfigFile(13); // the current file version is 13, replace it with 14
       
   901 	DoCfgOpenTests(14); // version 14 will be successfully processed (the 'C' style comment will be ignored) and stored in the settings table
       
   902 	}
       
   903 		
       
   904 void DoNewDbCfgOpenTest()
       
   905 	{
       
   906 	// Create Db5 - a config file already exists for this database
       
   907 	CreateDb5();
       
   908 	
       
   909 	// Open the shared, secure database Db5 - config ops should be applied on it
       
   910 	TheTest.Printf(_L("===NewDbCfg: Open shared, secure database\r\n"));
       
   911 	TInt err = TheDb.Open(KCfgDb5);
       
   912 	TEST2(err, KErrNone);
       
   913 	TRAP(err, CheckNumberRecordsL(KDb5CheckNumRecords)); // there should still be only 1 record in the table
       
   914 	TEST2(err, KErrNone);
       
   915 	TRAP(err, CheckNumberIndicesL(1)); // there should now be 1 index in the table
       
   916 	TEST2(err, KErrNone);
       
   917 	TheDb.Close();
       
   918 	CheckSystemSettingsTable(KCfgDb5, 1); // check that the ops in the specified config file have been applied
       
   919 		
       
   920 	// Open again the same shared, secure database - no config should occur (it has already been done)
       
   921 	TheTest.Printf(_L("===NewDbCfg: Open shared, secure database again\r\n"));
       
   922 	err = TheDb.Open(KCfgDb5);
       
   923 	TEST2(err, KErrNone);
       
   924 	TRAP(err, CheckNumberRecordsL(KDb5CheckNumRecords)); 
       
   925 	TEST2(err, KErrNone);
       
   926 	TRAP(err, CheckNumberIndicesL(1));
       
   927 	TEST2(err, KErrNone);
       
   928 	TheDb.Close();
       
   929 	CheckSystemSettingsTable(KCfgDb5, 1);
       
   930 	}
       
   931 	
       
   932 void DoCfgAttachTests(TInt aExpectedStoredVersion = 0)
       
   933 	{			
       
   934 	// Open a private, secure database - no config should occur
       
   935 	TheTest.Printf(_L("===CfgAttach: Open private, secure database\r\n"));
       
   936 	TInt err = TheDb.Open(KCfgDb3);
       
   937 	TEST2(err, KErrNone);
       
   938 	// Attach a shared, secure database - the db1 config file should not be processed
       
   939 	TheTest.Printf(_L("===CfgAttach: Attach shared, secure database\r\n"));
       
   940 	err = TheDb.Attach(KCfgDb1, KAttachDb1);
       
   941 	TEST2(err, KErrNone);
       
   942 	TheDb.Close();
       
   943 	CheckSystemSettingsTable(KCfgDb1, aExpectedStoredVersion); // check that the config file has not been processed for db1
       
   944 	CheckSystemSettingsTable(KCfgDb3, 0);
       
   945 	
       
   946 	// Open a public database - no config should occur
       
   947 	TheTest.Printf(_L("===CfgAttach: Open public database\r\n"));
       
   948     err = TheDb.Open(KCfgDb4);
       
   949 	TEST2(err, KErrNone);
       
   950 	// Attach a shared, secure database - no config should occur (there is no config file for this database)
       
   951 	TheTest.Printf(_L("===CfgAttach: Attach shared, secure database (that has no config file)\r\n"));
       
   952 	err = TheDb.Attach(KCfgDb2, KAttachDb2);
       
   953 	TEST2(err, KErrNone);
       
   954 	TheDb.Close();
       
   955 	CheckSystemSettingsTable(KCfgDb2, 0);
       
   956 	CheckSystemSettingsTable(KCfgDb4, 0);
       
   957 	}
       
   958 	
       
   959 void DoUpgradedCfgAttachTest()
       
   960 	{
       
   961 	// Upgrade the config file for KCfgDb1, i.e. replace v1 file with v2 file
       
   962 	UpgradeDbConfigFile(1);	
       
   963 	DoCfgAttachTests(2);
       
   964 	}
       
   965 	
       
   966 void DoBadCfgAttachTests()
       
   967 	{
       
   968 	// Test an empty config file
       
   969 	UpgradeDbConfigFile(2); // the current file version is 02, replace it with 03
       
   970 	DoCfgAttachTests(3); // version 03 will not be processed so no update to settings table
       
   971 	
       
   972 	// Test a config file with unsupported operations
       
   973 	UpgradeDbConfigFile(3); // the current file version is 03, replace it with 04
       
   974 	DoCfgAttachTests(4); // version 04 will not be processed so no update to settings table
       
   975 	
       
   976 	// Test a config file with only whitespace in it
       
   977 	UpgradeDbConfigFile(4); // the current file version is 04, replace it with 05
       
   978 	DoCfgAttachTests(5); // version 05 will not be processed so no update to settings table
       
   979 	
       
   980 	// Test a config file with operations on an invalid table
       
   981 	UpgradeDbConfigFile(5); // the current file version is 05, replace it with 06
       
   982 	DoCfgAttachTests(6); // version 06 will not be processed so no update to settings table
       
   983 	
       
   984 	// Test a config file that contains an invalid comment style
       
   985 	UpgradeDbConfigFile(6); // the current file version is 06, replace it with 07
       
   986 	DoCfgAttachTests(7); // version 07 will not be processed so no update to settings table
       
   987 	
       
   988 	// Test a config file that contains a sequence of statements as one statement (this is currently unsupported)
       
   989 	UpgradeDbConfigFile(7); // the current file version is 07, replace it with 08
       
   990 	DoCfgAttachTests(8); // version 08 will not be processed so no update to settings table
       
   991 	
       
   992 	// Test a config file that contains whitespace before and after the SQL statement
       
   993 	UpgradeDbConfigFile(8); // the current file version is 08, replace it with 09
       
   994 	DoCfgAttachTests(9); // version 09 will not be processed so no update to settings table
       
   995 	
       
   996 	// Test a config file that has a lower extension number
       
   997 	DowngradeDbConfigFile(9); // the current file version is 09, replace it with 08
       
   998 	DoCfgAttachTests(9); // version 08 will not be processed so no update to settings table
       
   999 	
       
  1000 	// Test a config file that has an invalid extension
       
  1001 	CreateCorruptDbConfigFile(8); // the current file version is 08, replace it with a file with an invalid extension
       
  1002 	DoCfgAttachTests(9); // the invalid file will not be processed so no update to settings table
       
  1003 	
       
  1004 	// Test two versions of the config file (two versions should not be present at the same time)
       
  1005 	CreateTwoVersionsOfConfigFile(); // the current file has an invalid extension, delete it and create version 10 and version 11
       
  1006 	DoCfgAttachTests(11); // neither version 10 or 11 will be processed so no update to settings table
       
  1007 		
       
  1008 	// Test a config file that contains an invalid statement and a valid statement
       
  1009 	UpgradeDbConfigFile(11); // the current file versions are 10 and 11, replace them with 12
       
  1010 	DoCfgAttachTests(12); // version 12 will not be processed so no update to settings table
       
  1011 
       
  1012 	// Test a config file that contains a SQL style comment
       
  1013 	UpgradeDbConfigFile(12); // the current file version is 12, replace it with 13
       
  1014 	DoCfgAttachTests(13); // version 13 will not be processed so no update to settings table
       
  1015 	
       
  1016 	// Test a config file that contains a 'C' style comment
       
  1017 	UpgradeDbConfigFile(13); // the current file version is 13, replace it with 14
       
  1018 	DoCfgAttachTests(14); // version 14 will not be processed so no update to settings table
       
  1019 	}
       
  1020 	
       
  1021 void DoNewDbCfgAttachTest()
       
  1022 	{
       
  1023 	// Create Db5 - a config file already exists for this
       
  1024 	CreateDb5();
       
  1025 	
       
  1026 	// Open a private, secure database - no config should occur
       
  1027 	TheTest.Printf(_L("===NewDbCfgAttach: Open private, secure database\r\n"));
       
  1028 	TInt err = TheDb.Open(KCfgDb3);
       
  1029 	TEST2(err, KErrNone);
       
  1030 	TRAP(err, CheckNumberRecordsL(KDb3CheckNumRecords));
       
  1031 	TEST2(err, KErrNone);
       
  1032 	TRAP(err, CheckNumberIndicesL(0)); 
       
  1033 	TEST2(err, KErrNone);
       
  1034 	
       
  1035 	// Attach a shared, secure database - the db5 config file should not be processed
       
  1036 	TheTest.Printf(_L("===NewDbCfgAttach: Attach shared, secure database\r\n"));
       
  1037 	err = TheDb.Attach(KCfgDb5, KAttachDb5);
       
  1038 	TEST2(err, KErrNone);
       
  1039 	TRAP(err, CheckNumberRecordsL(KDb5CheckNumRecords)); // there should still be only 1 record in the table
       
  1040 	TEST2(err, KErrNone);
       
  1041 	TRAP(err, CheckNumberIndicesL(0)); // there should still be no indices in the table
       
  1042 	TEST2(err, KErrNone);
       
  1043 	TheDb.Close();
       
  1044 	CheckSystemSettingsTable(KCfgDb5, 1); // check that the config file has been processed for db1
       
  1045 	CheckSystemSettingsTable(KCfgDb3, 0);
       
  1046 	}
       
  1047 	
       
  1048 void ResetStoredCollationDll()
       
  1049 	{
       
  1050 	// Note: We have to use SQLite directly to access the settings
       
  1051 	// table as the SQL Server denies permission to access this table	
       
  1052 	// as it is in a shared, secure database
       
  1053 	
       
  1054 	TParse parse;
       
  1055 	parse.Set(KCfgDb1, &KSqlSrvPrivatePath, 0);
       
  1056 	
       
  1057 	TBuf8<KMaxFileName + 1> dbFileName;
       
  1058 	dbFileName.Copy(parse.FullName());
       
  1059 	
       
  1060 	sqlite3 *dbHandle = NULL;
       
  1061 	TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
       
  1062 	TEST2(rc, SQLITE_OK);
       
  1063 	
       
  1064 	TBuf<100> queryBuf;
       
  1065 	queryBuf.Append(KResetCollationDllSql());	
       
  1066 	
       
  1067 	sqlite3_stmt* stmtHandle = NULL;
       
  1068 	const void* stmtTailZ = NULL;
       
  1069 	rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
       
  1070 	TEST2(rc, SQLITE_OK);
       
  1071 	
       
  1072 	rc = sqlite3_step(stmtHandle);
       
  1073 	TEST2(rc, SQLITE_DONE);
       
  1074 	
       
  1075 	sqlite3_finalize(stmtHandle);
       
  1076 	sqlite3_close(dbHandle);
       
  1077 	}
       
  1078 	
       
  1079 void CheckCollationDllUpdated()
       
  1080 	{
       
  1081 	// Note: We have to use SQLite directly to access the settings
       
  1082 	// table as the SQL Server denies permission to access this table
       
  1083 	// as it is in a shared, secure database
       
  1084 	
       
  1085 	TParse parse;
       
  1086 	parse.Set(KCfgDb1, &KSqlSrvPrivatePath, 0);
       
  1087 	
       
  1088 	TBuf8<KMaxFileName + 1> dbFileName;
       
  1089 	dbFileName.Copy(parse.FullName());
       
  1090 	
       
  1091 	sqlite3 *dbHandle = NULL;
       
  1092 	TInt rc = sqlite3_open((const char*)dbFileName.PtrZ(), &dbHandle);
       
  1093 	TEST2(rc, SQLITE_OK);
       
  1094 	
       
  1095 	TBuf<100> queryBuf;
       
  1096 	queryBuf.Append(KGetCollationDllSql());	
       
  1097 	
       
  1098 	sqlite3_stmt* stmtHandle = NULL;
       
  1099 	const void* stmtTailZ = NULL;
       
  1100 	rc = sqlite3_prepare16_v2(dbHandle, queryBuf.PtrZ(), -1, &stmtHandle, &stmtTailZ);
       
  1101 	TEST2(rc, SQLITE_OK);
       
  1102 	
       
  1103 	rc = sqlite3_step(stmtHandle);
       
  1104 	TEST2(rc, SQLITE_ROW);
       
  1105 	
       
  1106 	const TUint16* collationDllName = (const TUint16*)sqlite3_column_text16(stmtHandle, 0);
       
  1107 	TInt collationDllNameLen  = sqlite3_column_bytes(stmtHandle, 0) / sizeof(TUint16);
       
  1108 	TPtrC ptr(collationDllName, collationDllNameLen);
       
  1109 	
       
  1110 	rc = sqlite3_step(stmtHandle);
       
  1111 	TEST2(rc, SQLITE_DONE);
       
  1112 	
       
  1113 	sqlite3_finalize(stmtHandle);
       
  1114 	sqlite3_close(dbHandle);
       
  1115 	
       
  1116 	_LIT(KTestCollationDllName, "hjagafsff");//The same as the used in KResetCollationDllSql statement
       
  1117 	TEST(ptr != KTestCollationDllName);
       
  1118 	}
       
  1119 
       
  1120 /**
       
  1121 @SYMTestCaseID			SYSLIB-SQL-UT-4010
       
  1122 @SYMTestCaseDesc		New database configuration files feature - unit test.
       
  1123 						The test opens several test databases, and the database configuration
       
  1124 						file for one of the shared, secure databases is processed. This is
       
  1125 						repeated for a variety of versions of the database configuration file, 
       
  1126 						both valid and invalid. The same tests are repeated for when attaching, 
       
  1127 						rather than opening, the test databases. The test also verifies that
       
  1128 						reindexing occurs if necessary when a database is opened or attached,
       
  1129 						regardless of whether or not database configuration is also required.
       
  1130 						Finally, the test also verifies that a config file that exists before
       
  1131 						the database itself is created will be processed when the database is
       
  1132 						opened for the first time.				
       
  1133 @SYMTestPriority		High
       
  1134 @SYMTestActions			New database configuration files feature - unit test.
       
  1135 @SYMTestExpectedResults The test must not fail
       
  1136 @SYMCR 					LMAN-79SJ7L
       
  1137 */
       
  1138 void DoDbCfgTests()
       
  1139 	{
       
  1140 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4010 DoDbCfgTests "));
       
  1141 		
       
  1142 	// Do 'open' tests for new db config file feature
       
  1143 	DoCfgOpenTests();         // open the test databases
       
  1144  	DoUpgradedCfgOpenTest();  // upgrade the config file for db1 and reopen the test databases
       
  1145  	DoBadCfgOpenTests();      // corrupt the config file for db1 (in a variety of ways) and reopen the test databases
       
  1146  	DoNewDbCfgOpenTest();		  // create a db for which a config file already exists and then open the db
       
  1147  
       
  1148  	// Recreate the original dbs and config files
       
  1149  	DeleteCfgFilesAndDbs();
       
  1150  	CreateCfgFilesAndDbs();
       
  1151 
       
  1152  	// Do 'attach' tests for new db config file feature
       
  1153 	DoCfgAttachTests(1);		// attach the test databases
       
  1154  	DoUpgradedCfgAttachTest(); // upgrade the config file for db1 and reattach the test databases
       
  1155  	DoBadCfgAttachTests();     // corrupt the config file for db1 (in a variety of ways) and reattach the test databases	
       
  1156     DoNewDbCfgAttachTest();	   // create a db for which a config file already exists and then attach the db
       
  1157 	
       
  1158 	// Recreate the original dbs and config files
       
  1159  	DeleteCfgFilesAndDbs();
       
  1160  	CreateCfgFilesAndDbs();
       
  1161  	
       
  1162  	// Do the test that causes both reindexing and db configuration to occur when db1 is opened
       
  1163 	ResetStoredCollationDll();
       
  1164 	DoCfgOpenTests();
       
  1165 	CheckCollationDllUpdated();
       
  1166 	
       
  1167 	// Recreate the original dbs and config files
       
  1168  	DeleteCfgFilesAndDbs();
       
  1169  	CreateCfgFilesAndDbs();
       
  1170  	
       
  1171  	// Do the test that causes reindexing to occur when db1 is attached (no db configuration occurs for attach)
       
  1172 	ResetStoredCollationDll();
       
  1173 	DoCfgAttachTests(1);
       
  1174 	CheckCollationDllUpdated(); // db1's stored collation dll name should now match db3's (to which Db1 is attached) stored collation name
       
  1175 	}	
       
  1176 		
       
  1177 /**
       
  1178 @SYMTestCaseID			SYSLIB-SQL-UT-4013
       
  1179 @SYMTestCaseDesc		New database configuration files feature - OOM test.
       
  1180 						The test opens a shared secure database for which there
       
  1181 						exists a database configuration file that is to be processed.
       
  1182 						The open call is executed within an OOM loop, which causes
       
  1183 						an OOM error to occur at different stages of the open call. 
       
  1184 						The test verifies that OOM errors are handled correctly and 
       
  1185 						that on the final loop - when no OOM errors occur - the database is 
       
  1186 						successfully opened and the database configuration file is processed.	
       
  1187 @SYMTestPriority		High
       
  1188 @SYMTestActions			New database configuration files feature - OOM test.
       
  1189 @SYMTestExpectedResults The test must not fail
       
  1190 @SYMCR 					LMAN-79SJ7L
       
  1191 */
       
  1192 void DoDbCfgOOMTests()
       
  1193 	{
       
  1194 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4013 DoDbCfgOOMTests "));
       
  1195 
       
  1196 	// Recreate the original dbs and config files
       
  1197 	DeleteCfgFilesAndDbs();
       
  1198 	CreateCfgFilesAndDbs();
       
  1199 	
       
  1200 	// The server is stopped at the end of CreateCfgFilesAndDbs().
       
  1201 	// Before the test loop below begins we attach Db1 so that the 
       
  1202 	// server starts up again and stores Db1's security policy in
       
  1203 	// CSqlServer::iSecurityMap. Otherwise there will be unmatching 
       
  1204 	// allocated cells in the test below. Do not call Detach() before 
       
  1205 	// Close(). We 'attach' Db1 here rather than 'open' it because 
       
  1206 	// open is the API that we want to test in the while loop
       
  1207 	TInt err = TheDb.Open(KCfgDb3);
       
  1208 	TEST2(err, KErrNone);
       
  1209 	err = TheDb.Attach(KCfgDb1, KAttachDb1);
       
  1210 	TEST2(err, KErrNone);
       
  1211 	TheDb.Close();
       
  1212 	
       
  1213 	err = KErrNoMemory;
       
  1214 	TInt failingAllocationNo = 0;
       
  1215 	while(err == KErrNoMemory)
       
  1216 		{		
       
  1217 		MarkHandles();
       
  1218 		MarkAllocatedCells();
       
  1219 		
       
  1220 		__UHEAP_MARK;
       
  1221 
       
  1222 		TheTest.Printf(_L("%d\r"), failingAllocationNo + 1);
       
  1223 
       
  1224 		// Set failure rate
       
  1225 		TSqlResourceTester::SetDbHeapFailure(RHeap::EDeterministic, ++failingAllocationNo);
       
  1226 		err = TheDb.Open(KCfgDb1);
       
  1227 		if(err != KErrNoMemory)
       
  1228 			{
       
  1229 			TEST2(err, KErrNone);
       
  1230 			TheDb.Close();
       
  1231 			if(GuessSystemSettingsTable(KCfgDb1, 0))
       
  1232 				{
       
  1233 				err = KErrNoMemory;
       
  1234 				}
       
  1235 			}
       
  1236 		
       
  1237 		// Reset failure rate
       
  1238 		TSqlResourceTester::SetDbHeapFailure(RHeap::ENone, 0);
       
  1239 		
       
  1240 		TheDb.Close();
       
  1241 		
       
  1242 		__UHEAP_MARKEND;
       
  1243 
       
  1244 		CheckAllocatedCells();	    	
       
  1245 		CheckHandles();	    	
       
  1246 		}
       
  1247 	TEST2(err, KErrNone);
       
  1248 	TheTest.Printf(_L("\r\n"));
       
  1249 	CheckSystemSettingsTable(KCfgDb1, 1); // check that the settings table has been updated with v01 of the config file
       
  1250 	}
       
  1251 	
       
  1252 /**
       
  1253 @SYMTestCaseID			SYSLIB-SQL-UT-4014
       
  1254 @SYMTestCaseDesc		New database configuration files feature - File I/O failures test.
       
  1255 						The test opens a shared secure database for which there
       
  1256 						exists a database configuration file that is to be processed.
       
  1257 						The open call is executed within a file I/O failure loop, which
       
  1258 						causes a selection of file I/O errors to occur at different stages 
       
  1259 						of the open call. 
       
  1260 						The test verifies that file I/O errors are handled correctly and 
       
  1261 						that on the final loop - when no file I/O errors occur - the database 
       
  1262 						is successfully opened and the database configuration file is processed.
       
  1263 						NOTE: This test also acts as the test case for defect DEF116688.
       
  1264 @SYMTestPriority		High
       
  1265 @SYMTestActions			New database configuration files feature - File I/O failures test.
       
  1266 @SYMTestExpectedResults The test must not fail
       
  1267 @SYMCR					LMAN-79SJ7L
       
  1268 */
       
  1269 void DoDbCfgFileIOFailuresTests()
       
  1270 	{
       
  1271 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4014 DoDbCfgFileIOFailuresTests "));
       
  1272 
       
  1273 	// Recreate the original dbs and config files
       
  1274 	DeleteCfgFilesAndDbs();
       
  1275 	CreateCfgFilesAndDbs();
       
  1276 	
       
  1277 	// The server is stopped at the end of CreateCfgFilesAndDbs().
       
  1278 	// Before the test loop below begins we start the server again
       
  1279 	// by opening Db3) so that any server start up file i/o ops will 
       
  1280 	// succeed. We don't open Db1 here because opening Db1 is what 
       
  1281 	// we want to test in the while loop
       
  1282 	TInt err = TheDb.Open(KCfgDb3);
       
  1283 	TEST2(err, KErrNone);
       
  1284 	TheDb.Close();
       
  1285 
       
  1286 	TBool isFinished = EFalse;
       
  1287 	err = KErrNotFound;
       
  1288 	TInt iter = 0;
       
  1289 	TheTest.Printf(_L("Iteration\r\n"));
       
  1290 	for(TInt cnt = 1; !isFinished; ++cnt)
       
  1291 		{	
       
  1292 		for(TInt fsError = KErrNotFound; fsError >= KErrUnderflow; --fsError) // errors -1 to -10 will be generated
       
  1293 			{
       
  1294 			TheTest.Printf(_L("%d/%d   \r"), ++iter, fsError);
       
  1295 			(void)TheFs.SetErrorCondition(fsError, cnt); // set error code and how soon it is to occur
       
  1296 			err = TheDb.Open(KCfgDb1);
       
  1297 			(void)TheFs.SetErrorCondition(KErrNone);
       
  1298 			TheDb.Close();
       
  1299 			if(err != KErrNone)
       
  1300 				{
       
  1301 				// An error has occured. We know that this means that the database 
       
  1302 				// configuration part of the open call wasn't reached (because the
       
  1303 				// database configuration part returns KErrNone even if it fails).
       
  1304 				// But check anyway that the database content is still the same as
       
  1305 				// before, i.e. the settings table has not been updated
       
  1306 				CheckSystemSettingsTable(KCfgDb1, 0);
       
  1307 				}
       
  1308 			else
       
  1309 				{
       
  1310 				// Either the database configuration file for Db1 has been successfully
       
  1311 				// processed or it failed part-way through being processed (KErrNone is 
       
  1312 				// returned in this case too).
       
  1313 				// If it was the former then the the settings table will have 
       
  1314 				// been updated to store v01 of the config file
       
  1315 				if(GuessSystemSettingsTable(KCfgDb1, 1))
       
  1316 					{
       
  1317 					isFinished = ETrue;	
       
  1318 					break;
       
  1319 					}
       
  1320 				}
       
  1321 			}
       
  1322 		}
       
  1323 	TheTest.Printf(_L("\r\n"));
       
  1324 	TEST2(err, KErrNone);		
       
  1325 	// Check that the database configuration was allowed to be successfully applied in one of the loops
       
  1326 	CheckSystemSettingsTable(KCfgDb1, 1); // check that the settings table has been updated with v01 of the config file		
       
  1327 	}
       
  1328 	
       
  1329 /**
       
  1330 @SYMTestCaseID			SYSLIB-SQL-UT-4015
       
  1331 @SYMTestCaseDesc		New database configuration files feature - Performance test.
       
  1332 						The test measures:
       
  1333 						- the startup time of the SQL Server when 0 and 4 database 
       
  1334 						configuration files exist
       
  1335 						- the time taken to open a shared, secure database when a 
       
  1336 						database configuration file does and does not exist for it
       
  1337 						- the time taken to open a shared, secure database when a 
       
  1338 						database configuration file exists for it but it has already
       
  1339 						been processed
       
  1340 						- the time taken to attach a shared, secure database when a 
       
  1341 						database configuration file does and does not exist for it
       
  1342 @SYMTestPriority		High
       
  1343 @SYMTestActions			New database configuration files feature - Performance test.
       
  1344 @SYMTestExpectedResults The test must not fail
       
  1345 @SYMCR 					LMAN-79SJ7L
       
  1346 */
       
  1347 void DoDbCfgPerfTests()
       
  1348 	{
       
  1349 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4015 DoDbCfgPerfTests "));
       
  1350 
       
  1351 	// Recreate the original dbs
       
  1352 	DeleteCfgFilesAndDbs();
       
  1353 	CreateCfgDbs(); 
       
  1354 	(void)KillProcess(KSqlSrvName); // stop the server
       
  1355 
       
  1356 	// Measure the start up time of the server when
       
  1357 	// there are no database configuration files to be cached.
       
  1358 	// Open Db4 (public db):
       
  1359 	// No reindexing required
       
  1360 	// Database configuration is not considered
       
  1361 	TUint32 start = User::FastCounter();
       
  1362 	TInt err = TheDb.Open(KCfgDb4);
       
  1363 	TUint32 end = User::FastCounter();
       
  1364 	TEST2(err, KErrNone);
       
  1365 	TRAP(err, CheckNumberRecordsL(KDb4CheckNumRecords));
       
  1366 	TEST2(err, KErrNone);
       
  1367 	TRAP(err, CheckNumberIndicesL(0));
       
  1368 	TEST2(err, KErrNone);
       
  1369 	TheDb.Close();
       
  1370 	CheckSystemSettingsTable(KCfgDb4, 0);
       
  1371 	TInt ms = CalcTimeMs(start, end);
       
  1372 	TheTest.Printf(_L("Execution time: Server startup (via Open call) - no database config files to cache: %d ms\r\n"), ms);
       
  1373 	
       
  1374 	// Measure the time to open Db1 when no database
       
  1375 	// configuration file exists for it.
       
  1376 	// Open Db1 (shared, secure db):
       
  1377 	// No reindexing required
       
  1378 	// Database configuration is considered but no config file is found
       
  1379 	start = User::FastCounter();
       
  1380 	err = TheDb.Open(KCfgDb1);
       
  1381 	end = User::FastCounter();
       
  1382 	TEST2(err, KErrNone);
       
  1383 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords));
       
  1384 	TEST2(err, KErrNone);
       
  1385 	TRAP(err, CheckNumberIndicesL(0));
       
  1386 	TEST2(err, KErrNone);
       
  1387 	TheDb.Close();
       
  1388 	CheckSystemSettingsTable(KCfgDb1, 0);
       
  1389 	ms = CalcTimeMs(start, end);
       
  1390 	TheTest.Printf(_L("Execution time: Open shared, secure Db1 - no config file is found: %d ms\r\n"), ms);
       
  1391 	
       
  1392 	// Measure the time to attach Db1 (database configuration will not be considered).
       
  1393 	// Attach Db1 (shared, secure db):
       
  1394 	// No reindexing required
       
  1395 	// Database configuration is not considered
       
  1396 	TheDb.Open(KCfgDb3);
       
  1397 	TEST2(err, KErrNone);
       
  1398 	start = User::FastCounter();	
       
  1399 	err = TheDb.Attach(KCfgDb1, KAttachDb1);
       
  1400 	end = User::FastCounter();
       
  1401 	TEST2(err, KErrNone);
       
  1402 	TheDb.Close();
       
  1403 	CheckSystemSettingsTable(KCfgDb3, 0);
       
  1404 	CheckSystemSettingsTable(KCfgDb1, 0);
       
  1405 	ms = CalcTimeMs(start, end);
       
  1406 	TheTest.Printf(_L("Execution time: Attach shared, secure Db1 - database config is not considered: %d ms\r\n"), ms);
       
  1407 	
       
  1408 	// Create the 4 version 01 config files now
       
  1409 	CreateCfgFiles(); 
       
  1410 	(void)KillProcess(KSqlSrvName); // stop the server so that the files are found when it is restarted
       
  1411 	
       
  1412 	// Measure the start up time of the server when
       
  1413 	// there are 4 database configuration files to be cached.
       
  1414 	// Open Db4 (public db):
       
  1415 	// No reindexing required
       
  1416 	// Database configuration is not considered
       
  1417 	start = User::FastCounter();
       
  1418 	err = TheDb.Open(KCfgDb4);
       
  1419 	end = User::FastCounter();
       
  1420 	TEST2(err, KErrNone);
       
  1421 	TRAP(err, CheckNumberRecordsL(KDb4CheckNumRecords));
       
  1422 	TEST2(err, KErrNone);
       
  1423 	TRAP(err, CheckNumberIndicesL(0));
       
  1424 	TEST2(err, KErrNone);
       
  1425 	TheDb.Close();
       
  1426 	CheckSystemSettingsTable(KCfgDb4, 0);
       
  1427 	ms = CalcTimeMs(start, end);
       
  1428 	TheTest.Printf(_L("Execution time: Server startup (via Open call) - 4 database config files to cache: %d ms\r\n"), ms);
       
  1429 	
       
  1430 	// Measure the time to open Db1 when a database
       
  1431 	// configuration file exists for it.
       
  1432 	// Open Db1 (shared, secure db):
       
  1433 	// No reindexing required
       
  1434 	// Database configuration is considered, a file is found and config is applied (3 indices are created)
       
  1435 	start = User::FastCounter();
       
  1436 	err = TheDb.Open(KCfgDb1);
       
  1437 	end = User::FastCounter();
       
  1438 	TEST2(err, KErrNone);
       
  1439 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords));
       
  1440 	TEST2(err, KErrNone);
       
  1441 	TRAP(err, CheckNumberIndicesL(3));
       
  1442 	TEST2(err, KErrNone);
       
  1443 	TheDb.Close();
       
  1444 	CheckSystemSettingsTable(KCfgDb1, 1);
       
  1445 	ms = CalcTimeMs(start, end);
       
  1446 	TheTest.Printf(_L("Execution time: Open shared, secure Db1 - config file is found and applied: %d ms\r\n"), ms);
       
  1447 	
       
  1448 	// Measure the time to open Db1 when a database
       
  1449 	// configuration file exists for it but is has already been processed.
       
  1450 	// Open Db1 (shared, secure db):
       
  1451 	// No reindexing required
       
  1452 	// Database configuration is considered, a file is found but it has already been processed
       
  1453 	start = User::FastCounter();
       
  1454 	err = TheDb.Open(KCfgDb1);
       
  1455 	end = User::FastCounter();
       
  1456 	TEST2(err, KErrNone);
       
  1457 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords));
       
  1458 	TEST2(err, KErrNone);
       
  1459 	TRAP(err, CheckNumberIndicesL(3));
       
  1460 	TEST2(err, KErrNone);
       
  1461 	TheDb.Close();
       
  1462 	CheckSystemSettingsTable(KCfgDb1, 1);
       
  1463 	ms = CalcTimeMs(start, end);
       
  1464 	TheTest.Printf(_L("Execution time: Open shared, secure Db1 - config file is found but already processed: %d ms\r\n"), ms);	
       
  1465 	
       
  1466 	// Measure the time to attach Db1 (database configuration will not be considered).
       
  1467 	// Attach Db1 (shared, secure db):
       
  1468 	// No reindexing required
       
  1469 	// Database configuration is not considered
       
  1470 	TheDb.Open(KCfgDb3);
       
  1471 	TEST2(err, KErrNone);
       
  1472 	start = User::FastCounter();	
       
  1473 	err = TheDb.Attach(KCfgDb1, KAttachDb1);
       
  1474 	end = User::FastCounter();
       
  1475 	TEST2(err, KErrNone);
       
  1476 	TheDb.Close();
       
  1477 	CheckSystemSettingsTable(KCfgDb3, 0);
       
  1478 	CheckSystemSettingsTable(KCfgDb1, 1);
       
  1479 	ms = CalcTimeMs(start, end);
       
  1480 	TheTest.Printf(_L("Execution time: Attach shared, secure Db1 - database config is not considered: %d ms\r\n"), ms);
       
  1481 	}
       
  1482 
       
  1483 void TestStatementsL()
       
  1484 	{
       
  1485 	_LIT(KDbName,					"attachDb");
       
  1486 	_LIT(KCreateIndex,				"CREATE INDEX idx ON tbl(ColA)");
       
  1487 	_LIT(KCreateIndexIfNotExists,   "CREATE INDEX IF NOT EXISTS idx ON tbl(ColA)");
       
  1488 	_LIT(KCreateUniqueIndex,		"CREATE UNIQUE INDEX idx ON tbl(ColA)");
       
  1489 	_LIT(KNonSupported,				"CREATE idx ON tbl(ColA)");
       
  1490 	TBuf<200> buf;
       
  1491 
       
  1492 	// supported statements
       
  1493 	
       
  1494 	TBool rc = IsStatementSupported(KCreateIndex, KDbName, buf); 
       
  1495 	TEST(rc);
       
  1496 	
       
  1497 	rc = IsStatementSupported(KCreateIndexIfNotExists, KDbName, buf); 
       
  1498 	TEST(rc);
       
  1499 
       
  1500 	// unsupported statements
       
  1501 	rc = IsStatementSupported(KCreateUniqueIndex, KDbName, buf); 
       
  1502 	TEST(!rc);
       
  1503 
       
  1504 	rc = IsStatementSupported(KNonSupported, KDbName, buf); 
       
  1505 	TEST(!rc);
       
  1506 	}
       
  1507 
       
  1508 /**
       
  1509 @SYMTestCaseID			SYSLIB-SQL-UT-4030
       
  1510 @SYMTestCaseDesc		Test IsStatementSupportedLC function.
       
  1511 						This function checks either SQL statement from DB configuration file is supported or not.
       
  1512 						In the case of supported statement, function allocates buffer and copies statement into that buffer.
       
  1513 						Call IsStatementSupportedLC on several supported and unsupported SQL statements.
       
  1514 @SYMTestPriority		High
       
  1515 @SYMTestActions			Test IsStatementSupportedLC function.
       
  1516 @SYMTestExpectedResults The test must not fail
       
  1517 @SYMDEF					DEF118058
       
  1518 */
       
  1519 void DoIsStatementSupportedTests()
       
  1520 	{
       
  1521 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4030 DoIsStatementSupportedTests "));
       
  1522 	TInt err = KErrNone;
       
  1523 	TRAP(err, TestStatementsL());
       
  1524 	TEST2(err, KErrNone);
       
  1525 	}
       
  1526 
       
  1527 void DoLongDbNameTest()
       
  1528 	{
       
  1529 	TheTest.Next(_L("'Long database name' tests"));
       
  1530 	//Create the database	
       
  1531  	RSqlSecurityPolicy securityPolicy;
       
  1532  	TInt err = DoCreateSecurityPolicy(securityPolicy);
       
  1533  	TEST2(err, KErrNone);
       
  1534  	err = TheDb.Create(KLongDbName1, securityPolicy);
       
  1535  	TEST2(err, KErrNone);
       
  1536  	err = TheDb.Exec(_L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
  1537  	TEST(err >= 0);
       
  1538  	err = TheDb.Exec(_L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"));
       
  1539  	TEST(err == 1);
       
  1540  	TheDb.Close();
       
  1541  	//Kill the server (to reload config file names at the server startup)
       
  1542 	(void)KillProcess(KSqlSrvName);
       
  1543 	///////////////////////////////////////////////////////////////////////
       
  1544 	TheTest.Printf(_L("Open a database with a long name\r\n"));
       
  1545 	//Create cfg file
       
  1546  	RFile file;
       
  1547 	TFileName fileName;
       
  1548 	err = file.Create(TheFs, KLongCfgName1, EFileRead | EFileWrite);
       
  1549 	TEST2(err, KErrNone);
       
  1550 	TPtrC8 pDb1((const TUint8*)KCfgConfigFileValidStmt().Ptr(), KCfgConfigFileValidStmt().Length());
       
  1551 	err = file.Write(pDb1);	
       
  1552 	file.Close();	
       
  1553 	TEST2(err, KErrNone);
       
  1554 	//Open the database
       
  1555 	err = TheDb.Open(KLongDbName1);
       
  1556 	TEST2(err, KErrNone);
       
  1557 	TRAP(err, CheckNumberRecordsL(KDb1CheckNumRecords)); // there should still be only 1 record in the table
       
  1558 	TEST2(err, KErrNone);
       
  1559 	TRAP(err, CheckNumberIndicesL(1)); // there should now be 1 index in the table
       
  1560 	TEST2(err, KErrNone);
       
  1561 	TheDb.Close();
       
  1562 	const TInt KVersion = 1;
       
  1563 	CheckSystemSettingsTable(KLongDbName1, KVersion); // check that the ops in the specified config file have been applied
       
  1564 	///////////////////////////////////////////////////////////////////////
       
  1565 	TheTest.Printf(_L("Attach a database with a long logical name\r\n"));
       
  1566 	//Attached database test
       
  1567 	//Recreate the database
       
  1568  	(void)RSqlDatabase::Delete(KLongDbName1);
       
  1569  	err = TheDb.Create(KLongDbName1, securityPolicy);
       
  1570  	TEST2(err, KErrNone);
       
  1571  	err = TheDb.Exec(_L("CREATE TABLE table1(i1 INTEGER, i2 INTEGER, i3 INTEGER)"));
       
  1572  	TEST(err >= 0);
       
  1573  	err = TheDb.Exec(_L("INSERT INTO table1 (i1,i2,i3) values(1,2,3)"));
       
  1574  	TEST(err == 1);
       
  1575  	TheDb.Close();
       
  1576  	//Kill the server (to reload config file names at the server startup)
       
  1577 	(void)KillProcess(KSqlSrvName);
       
  1578 	//Open the main database
       
  1579  	err = TheDb.Open(KCfgDb1);
       
  1580  	securityPolicy.Close();
       
  1581 	TEST2(err, KErrNone);
       
  1582 	//Attach a database with a very long logical name
       
  1583 	TFileName attachDbName;
       
  1584 	attachDbName.SetLength(KMaxFileName);
       
  1585 	attachDbName.Fill(TChar('A'));
       
  1586  	err = TheDb.Attach(KLongDbName1, attachDbName);
       
  1587 	TEST2(err, KErrNone);
       
  1588  	err = TheDb.Detach(attachDbName);
       
  1589 	TEST2(err, KErrNone);
       
  1590  	TheDb.Close();
       
  1591 	CheckSystemSettingsTable(KLongDbName1, KVersion); // check that the ops in the specified config file have been applied
       
  1592 	//Cleanup
       
  1593  	(void)RSqlDatabase::Delete(KLongDbName1);
       
  1594 	}
       
  1595 
       
  1596 #endif	//SYSLIBS_TEST
       
  1597 
       
  1598 TInt E32Main()
       
  1599 	{
       
  1600 	TheTest.Title();
       
  1601 	
       
  1602 	CTrapCleanup* tc = CTrapCleanup::New();
       
  1603 	TheTest(tc != NULL);
       
  1604 	
       
  1605 	__UHEAP_MARK;
       
  1606 
       
  1607 #ifdef SYSLIBS_TEST	
       
  1608 	TheTest.Start(_L("t_sqldbconfigfile tests"));
       
  1609 
       
  1610 	// Set up the test environment
       
  1611 	SetupTestEnv();
       
  1612 	//Init sqlite library
       
  1613 	sqlite3SymbianLibInit();
       
  1614 
       
  1615 	// Do tests for database config files
       
  1616 	DoDbCfgTests();
       
  1617 	
       
  1618 	// Do OOM tests for database config files
       
  1619 	DoDbCfgOOMTests();
       
  1620 	
       
  1621 	// Do file I/O failure tests for database config files
       
  1622 	DoDbCfgFileIOFailuresTests();
       
  1623 
       
  1624 	// Do performance tests for database config files
       
  1625 	DoDbCfgPerfTests();
       
  1626 
       
  1627 	// Test IsStatementSupportedLC function
       
  1628 	DoIsStatementSupportedTests();
       
  1629 
       
  1630 	//Test with a very long database file (and config file) name
       
  1631 	DoLongDbNameTest();
       
  1632  
       
  1633   	// Destroy the test environment
       
  1634  	DestroyTestEnv();
       
  1635 	sqlite3SymbianLibFinalize();
       
  1636 	CloseSTDLIB();
       
  1637 	
       
  1638 	TheTest.End();
       
  1639 #else
       
  1640  	TheTest.Start(_L("This test works only if the whole SQL component is built with SYSLIBS_TEST macro defined!"));
       
  1641 	TheTest.End();
       
  1642 #endif	
       
  1643 	
       
  1644 	__UHEAP_MARKEND;
       
  1645 	
       
  1646 	TheTest.Close();
       
  1647 	
       
  1648 	delete tc;
       
  1649 	
       
  1650 	User::Heap().Check();
       
  1651 	return KErrNone;
       
  1652 	}