persistentstorage/sql/TEST/t_sqlprivcage.cpp
changeset 0 08ec8eefde2f
child 8 fa9941cf3867
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2006-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 <bautils.h>
       
    18 #include <sqldb.h>
       
    19 
       
    20 ///////////////////////////////////////////////////////////////////////////////////////
       
    21 
       
    22 static RFs TheFs;
       
    23 RTest TheTest(_L("t_sqlprivcage test"));
       
    24 
       
    25 _LIT(KTestDir, "c:\\test\\");
       
    26 _LIT(KTestDb1, "c:\\private\\21212124\\t_sqlprivcage_1.db");
       
    27 _LIT(KTestDb2, "c:\\private\\21212124\\t_sqlprivcage_2.db");
       
    28 _LIT(KTestDbZ, "z:\\private\\21212124\\t_sqldb1.db");//Created outside this test
       
    29 _LIT(KTestDb,  "\\private\\21212124\\t_sqlprivcage_3.db");
       
    30 TParse TheFileNameParse;
       
    31 
       
    32 static RCriticalSection ThreadCritSect;
       
    33 static RCriticalSection MainCritSect;
       
    34 
       
    35 _LIT(KPanicCategory, "TransFail");
       
    36 const TInt KPanicCode = 1111;
       
    37 
       
    38 ///////////////////////////////////////////////////////////////////////////////////////
       
    39 
       
    40 //Deletes all created test files.
       
    41 void DeleteTestFiles()
       
    42 	{
       
    43 	if(TheFileNameParse.FullName().Length() > 0)
       
    44 		{
       
    45 		(void)RSqlDatabase::Delete(TheFileNameParse.FullName());
       
    46 		}
       
    47 	(void)RSqlDatabase::Delete(KTestDb2);
       
    48 	(void)RSqlDatabase::Delete(KTestDb1);
       
    49 	}
       
    50 
       
    51 ///////////////////////////////////////////////////////////////////////////////////////
       
    52 ///////////////////////////////////////////////////////////////////////////////////////
       
    53 //Test macros and functions
       
    54 void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse)
       
    55 	{
       
    56 	if(!aValue)
       
    57 		{
       
    58 		DeleteTestFiles();
       
    59 		if(aPrintThreadName)
       
    60 			{
       
    61 			RThread th;
       
    62 			TName name = th.Name();
       
    63 			RDebug::Print(_L("*** Thread %S, Line %d\r\n"), &name, aLine);
       
    64 			}
       
    65 		else
       
    66 			{
       
    67 			RDebug::Print(_L("*** Line %d\r\n"), aLine);
       
    68 			}
       
    69 		TheTest(EFalse, aLine);
       
    70 		}
       
    71 	}
       
    72 void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse)
       
    73 	{
       
    74 	if(aValue != aExpected)
       
    75 		{
       
    76 		DeleteTestFiles();
       
    77 		if(aPrintThreadName)
       
    78 			{
       
    79 			RThread th;
       
    80 			TName name = th.Name();
       
    81 			RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue);
       
    82 			}
       
    83 		else
       
    84 			{
       
    85 			RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
       
    86 			}
       
    87 		TheTest(EFalse, aLine);
       
    88 		}
       
    89 	}
       
    90 #define TEST(arg) ::Check1((arg), __LINE__)
       
    91 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
       
    92 #define TTEST(arg) ::Check1((arg), __LINE__, ETrue)
       
    93 #define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue)
       
    94 
       
    95 ///////////////////////////////////////////////////////////////////////////////////////
       
    96 
       
    97 //Creates file session instance and the test directory
       
    98 void CreateTestEnv()
       
    99     {
       
   100 	TInt err = TheFs.Connect();
       
   101 	TEST2(err, KErrNone);
       
   102 
       
   103 	err = TheFs.CreatePrivatePath(EDriveC);
       
   104 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   105 
       
   106 	err = TheFs.MkDir(KTestDir);
       
   107 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   108 	}
       
   109 
       
   110 ///////////////////////////////////////////////////////////////////////////////////////
       
   111 
       
   112 /**
       
   113 @SYMTestCaseID			SYSLIB-SQL-CT-1764
       
   114 @SYMTestCaseDesc		The test creates a database in the test application's private data cage.
       
   115 						Then the test does some operations with the created private database:
       
   116 						create table, insert records, select records, transactions, delete database.
       
   117 						The tests verifies that the SQL server can create a database in the application's
       
   118 						private data cage and can operate with the database.
       
   119 @SYMTestPriority		High
       
   120 @SYMTestActions			SQL, Private database test.
       
   121 @SYMTestExpectedResults Test must not fail
       
   122 @SYMREQ					REQ5792
       
   123                         REQ5793
       
   124 */	
       
   125 void SimpleDbOpTest()
       
   126 	{
       
   127 	//Create private database
       
   128 	RSqlDatabase db;
       
   129 	TInt err = db.Create(KTestDb1);
       
   130 	TEST2(err, KErrNone);
       
   131 	
       
   132 	//Execute some operations with the private database
       
   133 	err = db.Exec(_L8("CREATE TABLE A(ID INTEGER)"));
       
   134 	TEST(err >= 0);	
       
   135 	err = db.Exec(_L8("INSERT INTO A(ID) VALUES(1);INSERT INTO A(ID) VALUES(2);INSERT INTO A(ID) VALUES(3);"));
       
   136 	TEST(err >= 0);	
       
   137 
       
   138 	//Check written records
       
   139 	RSqlStatement stmt;
       
   140 	err = stmt.Prepare(db, _L8("SELECT * FROM A"));
       
   141 	TEST2(err, KErrNone);
       
   142 	err = stmt.Next();
       
   143 	TEST2(err, KSqlAtRow);
       
   144 	TEST2(stmt.ColumnInt(0), 1);
       
   145 	err = stmt.Next();
       
   146 	TEST2(err, KSqlAtRow);
       
   147 	TEST2(stmt.ColumnInt(0), 2);
       
   148 	err = stmt.Next();
       
   149 	TEST2(err, KSqlAtRow);
       
   150 	TEST2(stmt.ColumnInt(0), 3);
       
   151 	err = stmt.Next();
       
   152 	TEST2(err, KSqlAtEnd);
       
   153 	stmt.Close();
       
   154 
       
   155 	db.Close();
       
   156 	//Open private database
       
   157 	err = db.Open(KTestDb1);
       
   158 	TEST2(err, KErrNone);
       
   159 
       
   160 	//Execute a DELETE transaction
       
   161 	err = db.Exec(_L8("BEGIN IMMEDIATE TRANSACTION"));
       
   162 	TEST(err >= 0);	
       
   163 
       
   164 	err = db.Exec(_L8("DELETE FROM A WHERE ID > 1"));
       
   165 	TEST(err >= 0);	
       
   166 
       
   167 	err = db.Exec(_L8("COMMIT TRANSACTION"));
       
   168 	TEST(err >= 0);	
       
   169 
       
   170 	//Check records left
       
   171 	err = stmt.Prepare(db, _L8("SELECT * FROM A"));
       
   172 	TEST2(err, KErrNone);
       
   173 	err = stmt.Next();
       
   174 	TEST2(err, KSqlAtRow);
       
   175 	TEST2(stmt.ColumnInt(0), 1);
       
   176 	err = stmt.Next();
       
   177 	TEST2(err, KSqlAtEnd);
       
   178 	stmt.Close();
       
   179 
       
   180 	//Open private database which is on drive Z and with the same name
       
   181 	RSqlDatabase db2;
       
   182 	err = db2.Open(KTestDbZ);
       
   183 	TEST2(err, KErrNone);
       
   184 	//An attempt to write to a read-only database
       
   185 	err = db2.Exec(_L("INSERT INTO A VALUES(6)"));
       
   186 	TheTest.Printf(_L(" === Read-only private database. RSqlDatabase::Exec() returned err=%d\r\n"), err);
       
   187 	TEST(err != KErrNone);
       
   188 	//Check records
       
   189 	err = stmt.Prepare(db2, _L8("SELECT * FROM A"));
       
   190 	TEST2(err, KErrNone);
       
   191 	err = stmt.Next();
       
   192 	TEST2(err, KSqlAtRow);
       
   193 	TEST2(stmt.ColumnInt(0), 1);
       
   194 	err = stmt.Next();
       
   195 	TEST2(err, KSqlAtEnd);
       
   196 	stmt.Close();
       
   197 	db2.Close();
       
   198 	
       
   199 	db.Close();
       
   200 	err = RSqlDatabase::Delete(KTestDb1);
       
   201 	TEST2(err, KErrNone);
       
   202 
       
   203 	//Create private database on drive different than C:
       
   204 	for(TInt drvNum=EDriveD;drvNum<=EDriveZ;++drvNum)
       
   205 		{
       
   206 		TDriveUnit drvUnit(drvNum);
       
   207 		TPtrC drvName = drvUnit.Name();
       
   208 		TheFileNameParse.Set(KTestDb, &drvName, 0);
       
   209 		//Check if it is possible to create application's private data cage on drvNum drive.	
       
   210 		err = TheFs.CreatePrivatePath(drvNum);
       
   211 		if(err == KErrNone || err == KErrAlreadyExists)
       
   212 			{
       
   213 			(void)RSqlDatabase::Delete(TheFileNameParse.FullName());
       
   214 			err = db.Create(TheFileNameParse.FullName());
       
   215 			if(err == KErrNone)
       
   216 				{
       
   217 				//Execute some operations with the private database
       
   218 				err = db.Exec(_L8("BEGIN IMMEDIATE TRANSACTION"));
       
   219 				TEST(err >= 0);	
       
   220 				err = db.Exec(_L8("CREATE TABLE A(ID INTEGER)"));
       
   221 				TEST(err >= 0);	
       
   222 				err = db.Exec(_L8("INSERT INTO A(ID) VALUES(1);INSERT INTO A(ID) VALUES(2);INSERT INTO A(ID) VALUES(3);"));
       
   223 				TEST(err >= 0);	
       
   224 				err = db.Exec(_L8("COMMIT TRANSACTION"));
       
   225 				TEST(err >= 0);	
       
   226 				db.Close();
       
   227 				err = RSqlDatabase::Delete(TheFileNameParse.FullName());
       
   228 				TEST2(err, KErrNone);
       
   229 				break;
       
   230 				}
       
   231 			}
       
   232 		TheFileNameParse.Set(KNullDesC, 0, 0);
       
   233 		}
       
   234 		
       
   235 	//An attempt to create/open "C:[21212122]BBDb2.db" - this test has no enough rights to do that.
       
   236 	//...open as a non-secure database
       
   237 	err = db.Open(_L("C:[21212122]BBDb2.db"));
       
   238 	TEST2(err, KErrPermissionDenied);
       
   239 	//...create as a non-secure database
       
   240 	err = db.Create(_L("C:[21212122]BBDb2.db"));
       
   241 	TEST2(err, KErrArgument);//secure database name, no security policy
       
   242 	//...create as a secure database
       
   243 	RSqlSecurityPolicy dbSecurity;
       
   244 	TSecurityPolicy policy(TSecurityPolicy::EAlwaysPass);
       
   245 	err = dbSecurity.Create(policy);
       
   246 	TEST2(err, KErrNone);
       
   247 	err = db.Create(_L("C:[21212122]BBDb2.db"), dbSecurity);
       
   248 	TEST2(err, KErrPermissionDenied);
       
   249 	dbSecurity.Close();
       
   250 
       
   251 	//An attempt to delete "C:[21212122]BBDb2.db" - this test has no enough rights to do that.
       
   252 	err = RSqlDatabase::Delete(_L("C:[21212122]BBDb2.db"));
       
   253 	TEST2(err, KErrPermissionDenied);
       
   254 	}
       
   255 
       
   256 /**
       
   257 @SYMTestCaseID			SYSLIB-SQL-CT-1765
       
   258 @SYMTestCaseDesc		The test creates two databases in the test application's private data cage.
       
   259 						Then the test inserts some records in both databases using separate RSqlDatabase objects.
       
   260 						The test closes both databases, then reopens the first one and attaches th second one.
       
   261 						Again, the test inserts some records in both databases, using single RSqlDatabase object.
       
   262 						The test reads the inserted records and verifies their column values.
       
   263 						The tests verifies that the SQL server can create a database in the application's
       
   264 						private data cage, can operate with the database and can attach private databases.
       
   265 @SYMTestPriority		High
       
   266 @SYMTestActions			SQL, Attach private database test.
       
   267 @SYMTestExpectedResults Test must not fail
       
   268 @SYMREQ					REQ5792
       
   269                         REQ5793
       
   270 */	
       
   271 void AttachDbOpTest()
       
   272 	{
       
   273 	//Create private database 1
       
   274 	RSqlDatabase db1;
       
   275 	TInt err = db1.Create(KTestDb1);
       
   276 	TEST2(err, KErrNone);
       
   277 	//Execute some operations with private database 1
       
   278 	err = db1.Exec(_L8("CREATE TABLE A(ID INTEGER)"));
       
   279 	TEST(err >= 0);	
       
   280 	err = db1.Exec(_L8("INSERT INTO A(ID) VALUES(1)"));
       
   281 	TEST2(err, 1);
       
   282 	db1.Close();
       
   283 
       
   284 	//Create private database 2
       
   285 	RSqlDatabase db2;
       
   286 	err = db2.Create(KTestDb2);
       
   287 	TEST2(err, KErrNone);
       
   288 	//Execute some operations with private database 2
       
   289 	err = db2.Exec(_L8("CREATE TABLE A(ID INTEGER, T TEXT)"));
       
   290 	TEST(err >= 0);	
       
   291 	err = db2.Exec(_L8("INSERT INTO A(ID, T) VALUES(1, 'NAME-NAME-NAME')"));
       
   292 	TEST2(err, 1);
       
   293 	db2.Close();
       
   294 
       
   295 	//Open database 1, attach database 2
       
   296 	RSqlDatabase db;
       
   297 	err = db.Open(KTestDb1);
       
   298 	TEST2(err, KErrNone);
       
   299 	err = db.Attach(KTestDb2, _L("Db2"));
       
   300 	TEST2(err, KErrNone);
       
   301 
       
   302 	//Insert some records
       
   303 	err = db.Exec(_L8("BEGIN IMMEDIATE TRANSACTION"));
       
   304 	TEST(err >= 0);	
       
   305 	err = db.Exec(_L8("INSERT INTO Main.A(ID) VALUES(2);INSERT INTO Db2.A(ID, T) VALUES(2, 'AAA');"));
       
   306 	TEST(err >= 0);	
       
   307 	err = db.Exec(_L8("COMMIT TRANSACTION"));
       
   308 	TEST(err >= 0);	
       
   309 	
       
   310 	err = db.Detach(_L("Db2"));
       
   311 	TEST2(err, KErrNone);
       
   312 	db.Close();
       
   313 	
       
   314 	//Verify inserted data in database 2
       
   315 	err = db.Open(KTestDb2);
       
   316 	TEST2(err, KErrNone);
       
   317 	
       
   318 	RSqlStatement stmt;
       
   319 	err = stmt.Prepare(db, _L8("SELECT * FROM A"));
       
   320 	TEST2(err, KErrNone);
       
   321 	
       
   322 	err = stmt.Next();
       
   323 	TEST2(err, KSqlAtRow);
       
   324 	TEST2(stmt.ColumnInt(0), 1);
       
   325 	TPtrC text;
       
   326 	err = stmt.ColumnText(1, text);
       
   327 	TEST2(err, KErrNone);
       
   328 	TEST(text == _L("NAME-NAME-NAME"));
       
   329 
       
   330 	err = stmt.Next();
       
   331 	TEST2(err, KSqlAtRow);
       
   332 	TEST2(stmt.ColumnInt(0), 2);
       
   333 	err = stmt.ColumnText(1, text);
       
   334 	TEST2(err, KErrNone);
       
   335 	TEST(text == _L("AAA"));
       
   336 	
       
   337 	err = stmt.Next();
       
   338 	TEST2(err, KSqlAtEnd);
       
   339 	stmt.Close();
       
   340 	db.Close();
       
   341 		
       
   342 	err = RSqlDatabase::Delete(KTestDb2);
       
   343 	TEST2(err, KErrNone);
       
   344 	err = RSqlDatabase::Delete(KTestDb1);
       
   345 	TEST2(err, KErrNone);
       
   346 	}
       
   347 
       
   348 /**
       
   349 @SYMTestCaseID			SYSLIB-SQL-CT-1766
       
   350 @SYMTestCaseDesc		The test creates a database in the test application's private data cage.
       
   351 						Then the test creates two RSqlDatabase obejcts connecting them to the same 
       
   352 						private database. The test inserts some records using both connections.
       
   353 						The test verifies that the inserted records are in the database file and
       
   354 						verifies the column values.
       
   355 						The test verifies that it is possible to make more than one connection to the
       
   356 						same private database and operate with the database using the database connections.
       
   357 @SYMTestPriority		High
       
   358 @SYMTestActions			SQL, Two database connections to the same private database test.
       
   359 @SYMTestExpectedResults Test must not fail
       
   360 @SYMREQ					REQ5792
       
   361                         REQ5793
       
   362 */	
       
   363 void TwoDbOpTest()
       
   364 	{
       
   365 	//Create private database
       
   366 	RSqlDatabase db1;
       
   367 	TInt err = db1.Create(KTestDb1);
       
   368 	TEST2(err, KErrNone);
       
   369 	
       
   370 	//Make a second connection with the test database
       
   371 	RSqlDatabase db2;
       
   372 	err = db2.Open(KTestDb1);
       
   373 	TEST2(err, KErrNone);
       
   374 	
       
   375 	//Execute some operations with the private database
       
   376 	err = db1.Exec(_L8("CREATE TABLE A(ID INTEGER)"));
       
   377 	TEST(err >= 0);	
       
   378 	err = db1.Exec(_L8("INSERT INTO A(ID) VALUES(1);"));
       
   379 	TEST2(err, 1);
       
   380 	err = db2.Exec(_L8("INSERT INTO A(ID) VALUES(2);"));
       
   381 	TEST2(err, 1);
       
   382 
       
   383 	//Verify inserted data
       
   384 	RSqlStatement stmt;
       
   385 	err = stmt.Prepare(db2, _L8("SELECT * FROM A"));
       
   386 	TEST2(err, KErrNone);
       
   387 	
       
   388 	err = stmt.Next();
       
   389 	TEST2(err, KSqlAtRow);
       
   390 	TEST2(stmt.ColumnInt(0), 1);
       
   391 	err = stmt.Next();
       
   392 	TEST2(err, KSqlAtRow);
       
   393 	TEST2(stmt.ColumnInt(0), 2);
       
   394 	err = stmt.Next();
       
   395 	TEST2(err, KSqlAtEnd);
       
   396 	stmt.Close();
       
   397 
       
   398 	db2.Close();
       
   399 	db1.Close();
       
   400 	err = RSqlDatabase::Delete(KTestDb1);
       
   401 	TEST2(err, KErrNone);
       
   402 	}
       
   403 
       
   404 //Test thread function.
       
   405 //The test thread opens a database, begins a transaction and then simulates a crash within the transaction.
       
   406 TInt ThreadFunc1(void*)
       
   407 	{
       
   408 	__UHEAP_MARK;
       
   409 	
       
   410 	CTrapCleanup* tc = CTrapCleanup::New();
       
   411 	TTEST(tc != NULL);
       
   412 
       
   413 	//Open test database
       
   414 	RSqlDatabase db;
       
   415 	TInt err = db.Open(KTestDb1);
       
   416 	TTEST2(err, KErrNone);
       
   417 
       
   418 	RDebug::Print(_L("---:WorkThread: Begin transaction. Exec SQL...\r\n"));
       
   419 	
       
   420 	//Begin a transaction
       
   421 	err = db.Exec(_L8("BEGIN IMMEDIATE TRANSACTION"));
       
   422 	TTEST(err >= 0);	
       
   423 
       
   424 	//Execute INSERT sql statements
       
   425 	err = db.Exec(_L8("INSERT INTO A(ID) VALUES(2);INSERT INTO A(ID) VALUES(3);"));
       
   426 	TTEST(err >= 0);	
       
   427 	
       
   428 	RDebug::Print(_L("---:WorkThread: Notify the main thread about the SQL statement execution\r\n"));
       
   429 	MainCritSect.Signal();
       
   430 
       
   431 	RDebug::Print(_L("---:WorkThread: Wait for permisson to continue...\r\n"));
       
   432 	ThreadCritSect.Wait();
       
   433 
       
   434 	User::SetJustInTime(EFalse);	// disable debugger panic handling
       
   435 
       
   436 	//Panic current thread without commiting the transaction (crash simulation)
       
   437 	RDebug::Print(_L("---:WorkThread: Panic!\r\n"));
       
   438 	User::Panic(KPanicCategory, KPanicCode);
       
   439 
       
   440 	delete tc;	
       
   441 	
       
   442 	__UHEAP_MARKEND;
       
   443 	
       
   444 	return KErrNone;		
       
   445 	}
       
   446 
       
   447 /**
       
   448 @SYMTestCaseID			SYSLIB-SQL-CT-1767
       
   449 @SYMTestCaseDesc		The test creates a database in the test application's private data cage.
       
   450 						The test does some operations with the database leaving it in state A.
       
   451 						Then the test creates a test thread and runs the thread. The test thread
       
   452 						opens a connection to the database, begins a transaction, inserts some data
       
   453 						and then simulates a crash within the transaction (kills the thread).
       
   454 						When the main thread takes the execution control, it reopens the database connection
       
   455 						and verifies that the database is in the same state A as it was before.
       
   456 @SYMTestPriority		High
       
   457 @SYMTestActions			SQL, Private database - transaction recovery test.
       
   458 @SYMTestExpectedResults Test must not fail
       
   459 @SYMREQ					REQ5792
       
   460                         REQ5793
       
   461 */	
       
   462 void TransDbOpTest()
       
   463 	{
       
   464 	//Create private database
       
   465 	RSqlDatabase db;
       
   466 	TInt err = db.Create(KTestDb1);
       
   467 	TEST2(err, KErrNone);
       
   468 	
       
   469 	//Execute some operations with the private database
       
   470 	err = db.Exec(_L8("CREATE TABLE A(ID INTEGER)"));
       
   471 	TEST(err >= 0);	
       
   472 	err = db.Exec(_L8("INSERT INTO A(ID) VALUES(1)"));
       
   473 	TEST2(err, 1);
       
   474 
       
   475 	//Check written records
       
   476 	RSqlStatement stmt;
       
   477 	err = stmt.Prepare(db, _L8("SELECT * FROM A"));
       
   478 	TEST2(err, KErrNone);
       
   479 	err = stmt.Next();
       
   480 	TEST2(err, KSqlAtRow);
       
   481 	TEST2(stmt.ColumnInt(0), 1);
       
   482 	err = stmt.Next();
       
   483 	TEST2(err, KSqlAtEnd);
       
   484 	stmt.Close();
       
   485 
       
   486 	db.Close();
       
   487 
       
   488 	//Run a test thread which will begin a transaction and then simulate a crash within the transaction
       
   489 	TEST2(ThreadCritSect.CreateLocal(), KErrNone);
       
   490 	ThreadCritSect.Wait();
       
   491 	TEST2(MainCritSect.CreateLocal(), KErrNone);
       
   492 	MainCritSect.Wait();
       
   493 	RDebug::Print(_L("+++:MainThread: Create the worker thread\r\n"));
       
   494 	_LIT(KThreadName, "WorkThrd");
       
   495 	RThread thread;
       
   496 	TEST2(thread.Create(KThreadName, &ThreadFunc1, 0x2000, 0x1000, 0x10000, NULL, EOwnerProcess), KErrNone);
       
   497 	TRequestStatus status;
       
   498 	thread.Logon(status);
       
   499 	TEST2(status.Int(), KRequestPending);
       
   500 	thread.Resume();
       
   501 	RDebug::Print(_L("+++:MainThread: Wait SQL statement(s) to be executed...\r\n"));
       
   502 	MainCritSect.Wait();
       
   503 	RDebug::Print(_L("+++:MainThread: Notify the worker thread to simulate a crash...\r\n"));
       
   504 	ThreadCritSect.Signal();
       
   505 	User::WaitForRequest(status);
       
   506 	User::SetJustInTime(ETrue);	// enable debugger panic handling
       
   507 	TEST2(thread.ExitType(), EExitPanic);
       
   508 	TEST2(thread.ExitReason(), KPanicCode);
       
   509 	thread.Close();
       
   510 	MainCritSect.Close();
       
   511 	ThreadCritSect.Close();
       
   512 
       
   513 	//Reopen the test database. The failed transaction must be rolled back.
       
   514 	err = db.Open(KTestDb1);
       
   515 	TEST2(err, KErrNone);
       
   516 	//Verify that the database content is the same as before the failed transaction
       
   517 	err = stmt.Prepare(db, _L8("SELECT * FROM A"));
       
   518 	TEST2(err, KErrNone);
       
   519 	err = stmt.Next();
       
   520 	TEST2(err, KSqlAtRow);
       
   521 	TEST2(stmt.ColumnInt(0), 1);
       
   522 	err = stmt.Next();
       
   523 	TEST2(err, KSqlAtEnd);
       
   524 	stmt.Close();
       
   525 	db.Close();
       
   526 
       
   527 	err = RSqlDatabase::Delete(KTestDb1);
       
   528 	TEST2(err, KErrNone);
       
   529 	}
       
   530 	
       
   531 void DoTests()
       
   532 	{
       
   533 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1764 Simple private db operations "));
       
   534 	SimpleDbOpTest();
       
   535 
       
   536 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1765 Private db operations - attach database "));
       
   537 	AttachDbOpTest();
       
   538 
       
   539 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1766 Private db operations - 2 database connections "));
       
   540 	TwoDbOpTest();
       
   541 
       
   542 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1767 Private db operations - transaction recovery "));
       
   543 	TransDbOpTest();
       
   544 	}
       
   545 
       
   546 TInt E32Main()
       
   547 	{
       
   548 	TheTest.Title();
       
   549 	
       
   550 	CTrapCleanup* tc = CTrapCleanup::New();
       
   551 	
       
   552 	__UHEAP_MARK;
       
   553 	
       
   554 	CreateTestEnv();
       
   555 	DeleteTestFiles();
       
   556 	DoTests();
       
   557 	DeleteTestFiles();
       
   558 	TheFs.Close();
       
   559 
       
   560 	__UHEAP_MARKEND;
       
   561 	
       
   562 	TheTest.End();
       
   563 	TheTest.Close();
       
   564 	
       
   565 	delete tc;
       
   566 
       
   567 	User::Heap().Check();
       
   568 	return KErrNone;
       
   569 	}