persistentstorage/sql/TEST/t_sqlgetfirststmt.cpp
changeset 0 08ec8eefde2f
child 55 44f437012c90
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2007-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 <e32debug.h>
       
    17 #include <e32test.h>
       
    18 #include <f32file.h>
       
    19 #include "sqlite3.h"
       
    20 #include <stdlib.h>
       
    21 #include "SqliteSymbian.h"
       
    22 #include "SqlAssert.h"
       
    23 
       
    24 ///////////////////////////////////////////////////////////////////////////////////////
       
    25 
       
    26 RTest TheTest(_L("t_SqlGetFirstStmt test"));
       
    27 RFs TheFs;
       
    28 sqlite3* TheSqliteDb;
       
    29 
       
    30 _LIT(KTestDir, "c:\\test\\");
       
    31 _LIT(KTestDatabase, "c:\\test\\DEF104744.db");
       
    32 _LIT8(KTestDatabaseZ, "c:\\test\\DEF104744.db\x0");
       
    33 
       
    34 ///////////////////////////////////////////////////////////////////////////////////////
       
    35 
       
    36 //Deletes all created test files.
       
    37 void DestroyTestEnv()
       
    38 	{
       
    39 	if(TheSqliteDb)
       
    40 		{
       
    41 		sqlite3_close(TheSqliteDb);	
       
    42 		TheSqliteDb = NULL;
       
    43 		}
       
    44 	(void)TheFs.Delete(KTestDatabase);
       
    45 	TheFs.Close();
       
    46 	}
       
    47 
       
    48 ///////////////////////////////////////////////////////////////////////////////////////
       
    49 ///////////////////////////////////////////////////////////////////////////////////////
       
    50 //Test macros and functions
       
    51 void Check1(TInt aValue, TInt aLine)
       
    52 	{
       
    53 	if(!aValue)
       
    54 		{
       
    55 		DestroyTestEnv();
       
    56 		RDebug::Print(_L("*** Line %d\r\n"), aLine);
       
    57 		TheTest(EFalse, aLine);
       
    58 		}
       
    59 	}
       
    60 void Check2(TInt aValue, TInt aExpected, TInt aLine)
       
    61 	{
       
    62 	if(aValue != aExpected)
       
    63 		{
       
    64 		DestroyTestEnv();
       
    65 		RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
       
    66 		TheTest(EFalse, aLine);
       
    67 		}
       
    68 	}
       
    69 #define TEST(arg) ::Check1((arg), __LINE__)
       
    70 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
       
    71 
       
    72 ///////////////////////////////////////////////////////////////////////////////////////
       
    73 ///////////////////////////////////////////////////////////////////////////////////////
       
    74 
       
    75 extern TPtrC GetFirstSqlStmt(TPtr& aString);
       
    76 
       
    77 #define PTR_ARG(buf) const_cast <TUint16*> (buf.Ptr()), buf.Length(), buf.Length()
       
    78 
       
    79 /**
       
    80 @SYMTestCaseID			SYSLIB-SQL-CT-1628
       
    81 @SYMTestCaseDesc		GetFirstSqlStmt() test
       
    82 						Tests the GetFirstSqlStmt() behaviour with a set of various SQL statements.
       
    83 @SYMTestPriority		High
       
    84 @SYMTestActions			GetFirstSqlStmt() test
       
    85 @SYMTestExpectedResults Test must not fail
       
    86 @SYMREQ					REQ5792
       
    87                         REQ5793
       
    88 */	
       
    89 void TestGetFirstSqlStmt()
       
    90 	{
       
    91 	TPtrC res;
       
    92 
       
    93 	TBuf<1> b2; b2.Append(TChar(0));
       
    94 	TPtr p2(PTR_ARG(b2));
       
    95 	res.Set(GetFirstSqlStmt(p2));
       
    96 	//Expected result: res = "\x0", p2 is NULL
       
    97 	TEST(res == b2);
       
    98 	TEST(!p2.Ptr());
       
    99 		
       
   100 	TBuf<2> b3; b3.Append(TChar(' ')); b3.Append(TChar(0));
       
   101 	TPtr p3(PTR_ARG(b3));
       
   102 	res.Set(GetFirstSqlStmt(p3));
       
   103 	//Expected result: res = " \x0", p3 is NULL
       
   104 	TEST(res == b3);
       
   105 	TEST(!p3.Ptr());
       
   106 	
       
   107 	TBuf<7> b4(_L(";; ;  ")); b4.Append(TChar(0));
       
   108 	TPtr p4(PTR_ARG(b4));
       
   109 	res.Set(GetFirstSqlStmt(p4));
       
   110 	//Expected result: res = "\x0", p4 = "; ;  \x0"
       
   111 	TEST(res.Length() == 1 && (TInt)res[0] == 0);
       
   112 	TInt accLen = res.Length();
       
   113 	TEST(p4 == b4.Right(b4.Length() - accLen));
       
   114 
       
   115 	res.Set(GetFirstSqlStmt(p4));
       
   116 	//Expected result: res = "\x0", p4 = " ;  \x0"
       
   117 	TEST(res.Length() == 1 && (TInt)res[0] == 0);
       
   118 	accLen += res.Length();
       
   119 	TEST(p4 == b4.Right(b4.Length() - accLen));
       
   120 	
       
   121 	res.Set(GetFirstSqlStmt(p4));
       
   122 	//Expected result: res = " \x0", p4 = "  \x0"
       
   123 	TEST((TInt)res[0] == (TInt)TChar(' ') && (TInt)res[1] == 0);
       
   124 	accLen += res.Length();
       
   125 	TEST(p4 == b4.Right(b4.Length() - accLen));
       
   126 	
       
   127 	res.Set(GetFirstSqlStmt(p4));
       
   128 	//Expected result: res = "  \x0", p4 is NULL
       
   129 	TEST((TInt)res[0] == (TInt)TChar(' ') && (TInt)res[1] == (TInt)TChar(' ') && (TInt)res[2] == 0);
       
   130 	TEST(!p4.Ptr());
       
   131 	
       
   132 	TBuf<20> b5(_L("SELECT * FROM A")); b5.Append(TChar(0));
       
   133 	TPtr p5(PTR_ARG(b5));
       
   134 	res.Set(GetFirstSqlStmt(p5));
       
   135 	//Expected result: res = "SELECT * FROM A\x0", p5 is NULL
       
   136 	TEST(res == b5);
       
   137 	TEST(!p5.Ptr());
       
   138 	
       
   139 	TBuf<20> b6(_L("SELECT * FROM A;")); b6.Append(TChar(0));
       
   140 	TPtr p6(PTR_ARG(b6));
       
   141 	res.Set(GetFirstSqlStmt(p6));
       
   142 	//Expected result: res = "SELECT * FROM A\x0", p6 = "\x0"
       
   143 	TEST(res == b6.Left(b6.Length() - 1));
       
   144 	TEST(p6.Length() == 1 && p6[0] == 0);
       
   145 
       
   146 	TBuf<40> b7(_L("/** Comment */ SELECT * FROM A;")); b7.Append(TChar(0));
       
   147 	TPtr p7(PTR_ARG(b7));
       
   148 	res.Set(GetFirstSqlStmt(p7));
       
   149 	//Expected result: res = "/** Comment */ SELECT * FROM A\x0", p7 = "\x0"
       
   150 	TEST(res == b7.Left(b7.Length() - 1));
       
   151 	TEST(p7.Length() == 1 && p7[0] == 0);
       
   152 
       
   153 	TBuf<40> b8(_L(" SELECT * FROM --Comment \r\n A;")); b8.Append(TChar(0));
       
   154 	TPtr p8(PTR_ARG(b8));
       
   155 	res.Set(GetFirstSqlStmt(p8));
       
   156 	//Expected result: res = " SELECT * FROM --Comment \r\n A\x0", p8 = "\x0"
       
   157 	TEST(res == b8.Left(b8.Length() - 1));
       
   158 	TEST(p8.Length() == 1 && p8[0] == 0);
       
   159 
       
   160 	TBuf<40> b9(_L("SELECT * FROM A; SELECT * FROM B")); b9.Append(TChar(0));
       
   161 	TPtr p9(PTR_ARG(b9));
       
   162 	res.Set(GetFirstSqlStmt(p9));
       
   163 	//Expected result: res = "SELECT * FROM A\x0", p9 = " SELECT * FROM B\x0"
       
   164 	TEST(res.Left(res.Length() - 1) == b9.Left(res.Length() - 1) && (TInt)res[res.Length() - 1] == 0);
       
   165 	accLen = res.Length();
       
   166 	TEST(p9 == b9.Right(b9.Length() - accLen));
       
   167 
       
   168 	res.Set(GetFirstSqlStmt(p9));
       
   169 	//Expected result: res = " SELECT * FROM B\x0", p9 is NULL
       
   170 	TEST(res == b9.Right(b9.Length() - accLen));
       
   171 	TEST(!p9.Ptr());
       
   172 
       
   173 	//Defect INC113060	
       
   174 	TBuf<255> b10(_L("UPDATE Playlist SET Name=';',Time='2007-09-20 12:31:33' WHERE UniqueId=640397473"));
       
   175 	TPtr p10(PTR_ARG(b10));
       
   176 	res.Set(GetFirstSqlStmt(p10));
       
   177 	//Expected results: res= original string
       
   178 	TEST(res.Compare(b10)==0);
       
   179 	TEST(!p10.Ptr());
       
   180 	
       
   181 	TBuf<255> firstStmt(_L("SELECT * FROM PlayList"));firstStmt.Append(TChar(0));
       
   182 	TBuf<255> b11(_L("SELECT * FROM PlayList;UPDATE Playlist SET Name=';',Time='2007-09-20 12:31:33' WHERE UniqueId=640397473"));
       
   183 	TPtr p11(PTR_ARG(b11));
       
   184 	res.Set(GetFirstSqlStmt(p11));
       
   185 	TEST(res.Compare(firstStmt)==0);
       
   186 	TEST(p11.Compare(b10)==0);
       
   187 	}
       
   188 
       
   189 /**
       
   190 @SYMTestCaseID			SYSLIB-SQL-UT-3433
       
   191 @SYMTestCaseDesc		Test for DEF104744 - RSqlStatement::Next() SQL Server crashes on ORDER BY clause.
       
   192 						The test creates a database with a table with 30 integer columns, then inserts 100
       
   193 						records. After that, sets the soft heap limit to be very low - 10K 
       
   194 						(to get sqlite3_release_memory() called by SQLITE ), creates a statement object 
       
   195 						and attempts to retrieve the inserted records in descending order.
       
   196 @SYMTestPriority		High
       
   197 @SYMTestActions			Test for DEF104744 - RSqlStatement::Next() SQL Server crashes on ORDER BY clause.
       
   198 @SYMTestExpectedResults Test must not fail
       
   199 @SYMDEF					DEF104744
       
   200 */
       
   201 void DEF104744()
       
   202 	{
       
   203 	(void)TheFs.Delete(KTestDatabase);
       
   204 	TheSqliteDb = NULL;
       
   205 	TInt err = sqlite3_open((const char*)KTestDatabaseZ().Ptr(), &TheSqliteDb);
       
   206 	TEST2(err, SQLITE_OK);
       
   207 	
       
   208 	_LIT8(KCreateTblSqlZ, "CREATE TABLE A1(F1 INTEGER,F2 INTEGER,F3 INTEGER,F4 INTEGER,F5 INTEGER,F6 INTEGER,F7 INTEGER,F8 INTEGER,F9 INTEGER,F10 INTEGER,F11 INTEGER,F12 INTEGER,F13 INTEGER,F14 INTEGER,F15 INTEGER,F16 INTEGER,F17 INTEGER,F18 INTEGER,F19 INTEGER,F20 INTEGER,F21 INTEGER,F22 INTEGER,F23 INTEGER,F24 INTEGER,F25 INTEGER,F26 INTEGER,F27 INTEGER,F28 INTEGER,F29 INTEGER,F30 INTEGER)\x0");
       
   209 	err = sqlite3_exec(TheSqliteDb, (const char*)KCreateTblSqlZ().Ptr(), 0, 0, 0);
       
   210 	TEST2(err, SQLITE_OK);
       
   211 
       
   212 	//Insert a 100 records
       
   213 	const TInt KTestRecCnt = 100;
       
   214 	_LIT8(KInsertSqlZ, "INSERT INTO A1(F1,F2 ,F3 ,F4 ,F5 ,F6 ,F7 ,F8 ,F9 ,F10,F11,F12,F13,F14,F15,F16,F17,F18,F19,F20,F21,F22,F23,F24,F25,F26,F27,F28,F29,F30) VALUES(:Prm1,:Prm2,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296,4294967296)\x0");
       
   215 	sqlite3_stmt* stmt1 = NULL;
       
   216 	err = sqlite3_prepare_v2(TheSqliteDb, (const char*)(KInsertSqlZ().Ptr()), -1, &stmt1, NULL);
       
   217 	TEST2(err, SQLITE_OK);
       
   218 	
       
   219 	_LIT8(KBeginSqlZ, "BEGIN\x0");
       
   220 	err = sqlite3_exec(TheSqliteDb, (const char*)KBeginSqlZ().Ptr(), 0, 0, 0);
       
   221 	TEST2(err, SQLITE_OK);
       
   222 	
       
   223 	for(TInt i=0;i<KTestRecCnt;++i)
       
   224 		{ 
       
   225 		err = sqlite3_bind_int(stmt1, 1, i);
       
   226 		TEST2(err, SQLITE_OK);
       
   227 		err = sqlite3_bind_int(stmt1, 2, i + 1);
       
   228 		TEST2(err, SQLITE_OK);
       
   229 		err = sqlite3_step(stmt1);
       
   230 		TEST2(err, SQLITE_DONE);
       
   231 		err = sqlite3_reset(stmt1);
       
   232 		TEST2(err, SQLITE_OK);
       
   233 		TInt cnt = sqlite3_changes(TheSqliteDb);
       
   234 		TEST2(cnt, 1);
       
   235 		}
       
   236 		
       
   237 	_LIT8(KCommitSqlZ, "COMMIT\x0");
       
   238 	err = sqlite3_exec(TheSqliteDb, (const char*)KCommitSqlZ().Ptr(), 0, 0, 0);
       
   239 	TEST2(err, SQLITE_OK);
       
   240 	sqlite3_finalize(stmt1);
       
   241 
       
   242 	sqlite3_soft_heap_limit(10 * 1024);//Setting very low soft heap limit - 10K
       
   243 
       
   244 	// Get the inserted record data in descending order.
       
   245 	sqlite3_stmt* stmt2 = NULL;
       
   246 	_LIT8(KSelectSqlZ,"SELECT * FROM A1 ORDER BY F1 DESC");
       
   247 	err = sqlite3_prepare_v2(TheSqliteDb, (const char*)(KSelectSqlZ().Ptr()), -1, &stmt2, NULL);
       
   248 	TEST2(err, SQLITE_OK);
       
   249 	err = sqlite3_step(stmt2);
       
   250 	TEST2(err, SQLITE_ROW);
       
   251 	sqlite3_finalize(stmt2);
       
   252 
       
   253 	sqlite3_close(TheSqliteDb); 
       
   254 	TheSqliteDb = NULL;
       
   255 	(void)TheFs.Delete(KTestDatabase);
       
   256 	}
       
   257 
       
   258 enum TStmtType {EStmt8, EStmt16};
       
   259 
       
   260 //This function attempts to execute sqlite3_prepare_v2() or sqlite3_prepare16_v2() in an "out of memory loop".
       
   261 //If the prepare call fails, the statement handle is expected to be NULL.
       
   262 void StmtHandleTest(TStmtType aStmtType)
       
   263 	{
       
   264 	TEST(TheSqliteDb != NULL);
       
   265 	for(TInt failingAllocationNo=1;;++failingAllocationNo)
       
   266 		{
       
   267 		__UHEAP_SETFAIL(RHeap::EFailNext, failingAllocationNo);
       
   268 		sqlite3_stmt* stmt = NULL;
       
   269 		TInt err = SQLITE_NOMEM;
       
   270 		if(aStmtType == EStmt8)
       
   271 			{
       
   272 			_LIT8(KSelectSqlZ,"SELECT * FROM A\x0");
       
   273 			err = sqlite3_prepare_v2(TheSqliteDb, (const char*)(KSelectSqlZ().Ptr()), -1, &stmt, NULL);
       
   274 			}
       
   275 		else
       
   276 			{
       
   277 			_LIT(KSelectSqlZ,"SELECT * FROM A\x0");
       
   278 			err = sqlite3_prepare16_v2(TheSqliteDb, (const char*)(KSelectSqlZ().Ptr()), -1, &stmt, NULL);
       
   279 			}
       
   280 		__UHEAP_SETFAIL(RHeap::ENone, 0);
       
   281 		if(err != SQLITE_OK)
       
   282 			{//The statement handle should be NULL if err is not SQLITE_OK
       
   283 			TEST(!stmt);
       
   284 			}
       
   285 		else
       
   286 			{
       
   287 			TEST(stmt != NULL);
       
   288 			sqlite3_finalize(stmt);
       
   289 			break;
       
   290 			}
       
   291 		}
       
   292 	}
       
   293 
       
   294 /**
       
   295 @SYMTestCaseID			SYSLIB-SQL-UT-3466
       
   296 @SYMTestCaseDesc		Test for DEF105444 SQL, sqlite3_prepare_v2() demonstrates non-atomic behaviour (handle leak).
       
   297 						The test creates a database with a table and inserts one record.
       
   298 						After that the test attempts to prepare a SELECT statement handle inside an "ouut of memory"
       
   299 						loop. If the prepare operation fails, the statement handle should be NULL.
       
   300 @SYMTestPriority		High
       
   301 @SYMTestActions			DEF105444 SQL, sqlite3_prepare_v2() demonstrates non-atomic behaviour (handle leak) 
       
   302 @SYMTestExpectedResults Test must not fail
       
   303 @SYMDEF					DEF105444
       
   304 */
       
   305 void DEF105444()
       
   306 	{
       
   307 	(void)TheFs.Delete(KTestDatabase);
       
   308 	TheSqliteDb = NULL;
       
   309 	TInt err = sqlite3_open((const char*)KTestDatabaseZ().Ptr(), &TheSqliteDb);
       
   310 	TEST2(err, SQLITE_OK);
       
   311 	
       
   312 	_LIT8(KCreateTblSqlZ, "CREATE TABLE A(Id INTEGER)\x0");
       
   313 	err = sqlite3_exec(TheSqliteDb, (const char*)KCreateTblSqlZ().Ptr(), 0, 0, 0);
       
   314 	TEST2(err, SQLITE_OK);
       
   315 
       
   316 	_LIT8(KInsertSqlZ, "INSERT INTO A(Id) VALUES(1)\x0");
       
   317 	err = sqlite3_exec(TheSqliteDb, (const char*)KInsertSqlZ().Ptr(), 0, 0, 0);
       
   318 	TEST2(err, SQLITE_OK);
       
   319 
       
   320 	StmtHandleTest(EStmt8);
       
   321 	StmtHandleTest(EStmt16);
       
   322 	
       
   323 	sqlite3_close(TheSqliteDb); 
       
   324 	TheSqliteDb = NULL;
       
   325 	(void)TheFs.Delete(KTestDatabase);
       
   326 	}
       
   327 
       
   328 void UtilFileNameTest()
       
   329 	{
       
   330 #ifdef _ASSERTIONS	
       
   331 	_LIT(KFileName, "bbb.db");
       
   332 	
       
   333 	_LIT(KFileName1, "c:\\aaa\\bbb.db\x0");
       
   334 	TPtrC p1 = Util::Filename(KFileName1().Ptr());
       
   335 	TEST(p1 == KFileName);
       
   336 	
       
   337 	_LIT(KFileName2, "c:/aaa/bbb.db\x0");
       
   338 	TPtrC p2 = Util::Filename(KFileName2().Ptr());
       
   339 	TEST(p2 == KFileName);
       
   340 	
       
   341 	_LIT(KFileName3, "bbb.db\x0");
       
   342 	TPtrC p3 = Util::Filename(KFileName3().Ptr());
       
   343 	TEST(p3 == KFileName);
       
   344 #else
       
   345 	TheTest.Printf(_L(" === This test case works only if the test is built with the _ASSERTIONS macro defined!\r\n"));
       
   346 #endif	
       
   347 	}
       
   348 
       
   349 void DoTests()
       
   350 	{
       
   351 	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1628 GetFirstSqlStmt() test "));
       
   352 	TestGetFirstSqlStmt();
       
   353 	
       
   354 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3433 DEF104744 SQL Server crashes on ORDER BY clause "));
       
   355 	DEF104744();
       
   356 
       
   357 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3466 DEF105444 SQL, sqlite3_prepare_v2() demonstrates non-atomic behaviour (handle leak) "));
       
   358 	DEF105444();
       
   359 
       
   360 	TheTest.Next(_L(" Util::Filename() test"));
       
   361 	UtilFileNameTest();
       
   362 	}
       
   363 
       
   364 //Creates file session instance and the test directory
       
   365 void CreateTestEnv()
       
   366     {
       
   367 	TInt err = TheFs.Connect();
       
   368 	TheTest(err == KErrNone);
       
   369 
       
   370 	err = TheFs.MkDir(KTestDir);
       
   371 	TEST(err == KErrNone || err == KErrAlreadyExists);
       
   372 	}
       
   373 
       
   374 TInt E32Main()
       
   375 	{
       
   376 	TheSqliteDb = NULL;
       
   377 	
       
   378 	TheTest.Title();
       
   379 	
       
   380 	CTrapCleanup* tc = CTrapCleanup::New();
       
   381 	
       
   382 	__UHEAP_MARK;
       
   383 
       
   384 	CreateTestEnv();
       
   385 	TInt err = sqlite3SymbianLibInit();
       
   386 	TEST2(err, KErrNone);
       
   387 	DoTests();
       
   388 	sqlite3SymbianLibFinalize();
       
   389 	DestroyTestEnv();
       
   390 
       
   391 	CloseSTDLIB();
       
   392 
       
   393 	__UHEAP_MARKEND;
       
   394 	
       
   395 	TheTest.End();
       
   396 	TheTest.Close();
       
   397 	
       
   398 	delete tc;
       
   399 
       
   400 	User::Heap().Check();
       
   401 	return KErrNone;
       
   402 	}