First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include "SqliteSymbian.h"
22 #include "SqlAssert.h"
24 ///////////////////////////////////////////////////////////////////////////////////////
26 RTest TheTest(_L("t_SqlGetFirstStmt test"));
30 _LIT(KTestDir, "c:\\test\\");
31 _LIT(KTestDatabase, "c:\\test\\DEF104744.db");
32 _LIT8(KTestDatabaseZ, "c:\\test\\DEF104744.db\x0");
34 ///////////////////////////////////////////////////////////////////////////////////////
36 //Deletes all created test files.
41 sqlite3_close(TheSqliteDb);
44 (void)TheFs.Delete(KTestDatabase);
48 ///////////////////////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////////////////////
50 //Test macros and functions
51 void Check1(TInt aValue, TInt aLine)
56 RDebug::Print(_L("*** Line %d\r\n"), aLine);
57 TheTest(EFalse, aLine);
60 void Check2(TInt aValue, TInt aExpected, TInt aLine)
62 if(aValue != aExpected)
65 RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue);
66 TheTest(EFalse, aLine);
69 #define TEST(arg) ::Check1((arg), __LINE__)
70 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
72 ///////////////////////////////////////////////////////////////////////////////////////
73 ///////////////////////////////////////////////////////////////////////////////////////
75 extern TPtrC GetFirstSqlStmt(TPtr& aString);
77 #define PTR_ARG(buf) const_cast <TUint16*> (buf.Ptr()), buf.Length(), buf.Length()
80 @SYMTestCaseID SYSLIB-SQL-CT-1628
81 @SYMTestCaseDesc GetFirstSqlStmt() test
82 Tests the GetFirstSqlStmt() behaviour with a set of various SQL statements.
84 @SYMTestActions GetFirstSqlStmt() test
85 @SYMTestExpectedResults Test must not fail
89 void TestGetFirstSqlStmt()
93 TBuf<1> b2; b2.Append(TChar(0));
95 res.Set(GetFirstSqlStmt(p2));
96 //Expected result: res = "\x0", p2 is NULL
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
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));
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));
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));
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);
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
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);
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);
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);
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));
168 res.Set(GetFirstSqlStmt(p9));
169 //Expected result: res = " SELECT * FROM B\x0", p9 is NULL
170 TEST(res == b9.Right(b9.Length() - accLen));
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);
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);
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
203 (void)TheFs.Delete(KTestDatabase);
205 TInt err = sqlite3_open((const char*)KTestDatabaseZ().Ptr(), &TheSqliteDb);
206 TEST2(err, SQLITE_OK);
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);
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);
219 _LIT8(KBeginSqlZ, "BEGIN\x0");
220 err = sqlite3_exec(TheSqliteDb, (const char*)KBeginSqlZ().Ptr(), 0, 0, 0);
221 TEST2(err, SQLITE_OK);
223 for(TInt i=0;i<KTestRecCnt;++i)
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);
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);
242 sqlite3_soft_heap_limit(10 * 1024);//Setting very low soft heap limit - 10K
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);
253 sqlite3_close(TheSqliteDb);
255 (void)TheFs.Delete(KTestDatabase);
258 enum TStmtType {EStmt8, EStmt16};
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)
264 TEST(TheSqliteDb != NULL);
265 for(TInt failingAllocationNo=1;;++failingAllocationNo)
267 __UHEAP_SETFAIL(RHeap::EFailNext, failingAllocationNo);
268 sqlite3_stmt* stmt = NULL;
269 TInt err = SQLITE_NOMEM;
270 if(aStmtType == EStmt8)
272 _LIT8(KSelectSqlZ,"SELECT * FROM A\x0");
273 err = sqlite3_prepare_v2(TheSqliteDb, (const char*)(KSelectSqlZ().Ptr()), -1, &stmt, NULL);
277 _LIT(KSelectSqlZ,"SELECT * FROM A\x0");
278 err = sqlite3_prepare16_v2(TheSqliteDb, (const char*)(KSelectSqlZ().Ptr()), -1, &stmt, NULL);
280 __UHEAP_SETFAIL(RHeap::ENone, 0);
282 {//The statement handle should be NULL if err is not SQLITE_OK
288 sqlite3_finalize(stmt);
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
307 (void)TheFs.Delete(KTestDatabase);
309 TInt err = sqlite3_open((const char*)KTestDatabaseZ().Ptr(), &TheSqliteDb);
310 TEST2(err, SQLITE_OK);
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);
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);
320 StmtHandleTest(EStmt8);
321 StmtHandleTest(EStmt16);
323 sqlite3_close(TheSqliteDb);
325 (void)TheFs.Delete(KTestDatabase);
328 void UtilFileNameTest()
331 _LIT(KFileName, "bbb.db");
333 _LIT(KFileName1, "c:\\aaa\\bbb.db\x0");
334 TPtrC p1 = Util::Filename(KFileName1().Ptr());
335 TEST(p1 == KFileName);
337 _LIT(KFileName2, "c:/aaa/bbb.db\x0");
338 TPtrC p2 = Util::Filename(KFileName2().Ptr());
339 TEST(p2 == KFileName);
341 _LIT(KFileName3, "bbb.db\x0");
342 TPtrC p3 = Util::Filename(KFileName3().Ptr());
343 TEST(p3 == KFileName);
345 TheTest.Printf(_L(" === This test case works only if the test is built with the _ASSERTIONS macro defined!\r\n"));
351 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1628 GetFirstSqlStmt() test "));
352 TestGetFirstSqlStmt();
354 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3433 DEF104744 SQL Server crashes on ORDER BY clause "));
357 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-3466 DEF105444 SQL, sqlite3_prepare_v2() demonstrates non-atomic behaviour (handle leak) "));
360 TheTest.Next(_L(" Util::Filename() test"));
364 //Creates file session instance and the test directory
367 TInt err = TheFs.Connect();
368 TheTest(err == KErrNone);
370 err = TheFs.MkDir(KTestDir);
371 TEST(err == KErrNone || err == KErrAlreadyExists);
380 CTrapCleanup* tc = CTrapCleanup::New();
385 TInt err = sqlite3SymbianLibInit();
386 TEST2(err, KErrNone);
388 sqlite3SymbianLibFinalize();
400 User::Heap().Check();