|
1 // Copyright (c) 2005-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 <e32std.h> |
|
17 #include <f32file.h> |
|
18 #include <e32test.h> |
|
19 #include <stdio.h> |
|
20 #include <stdlib.h> |
|
21 #include <string.h> |
|
22 #include <hal.h> |
|
23 #include <utf.h> //CnvUtfConverter |
|
24 #include "sqlite3.h" |
|
25 #include "SqliteSymbian.h" |
|
26 |
|
27 #define UNUSED_VAR(a) a = (a) |
|
28 |
|
29 //Forward declaration |
|
30 struct Mem; |
|
31 |
|
32 static RTest TheTest(_L ("t_sqlite.exe")); |
|
33 static CTrapCleanup* TheTrapCleanup = NULL; |
|
34 static RFs TheFs; |
|
35 |
|
36 //File-local buffer used for converted to UTF16 (from UTF8) strings or |
|
37 //for a temporary file name buffer. |
|
38 static TUint16 TheFileName[KMaxFileName + 1]; |
|
39 |
|
40 _LIT(KTestDir, "c:\\test\\"); |
|
41 |
|
42 const char KDbName1[] = "c:\\test\\t_sqlite1.db"; |
|
43 const char KDbName2[] = "c:\\test\\t_sqlite2.db"; |
|
44 _LIT(KContactsFile, "c:\\test\\Contacts.DB"); |
|
45 |
|
46 sqlite3 *TheDb1 = NULL, *TheDb2 = NULL; |
|
47 |
|
48 static TBuf<4096> TheBuf1; |
|
49 static TBuf<4096> TheBuf2; |
|
50 static TBuf8<512> TheBuf3; |
|
51 |
|
52 static TInt TheCmpFCallCnt = 0; |
|
53 static TInt TheCmpCCallCnt = 0; |
|
54 |
|
55 _LIT(KSimpleContactsSqlFile, "z:\\test\\add_simple_contacts.sql"); |
|
56 |
|
57 //In order to be able to compile the test, the following variables are defined (used inside the OS porting layer, when _SQLPROFILER macro is defined) |
|
58 #ifdef _SQLPROFILER |
|
59 TInt TheSqlSrvProfilerFileRead = 0; |
|
60 TInt TheSqlSrvProfilerFileWrite = 0; |
|
61 TInt TheSqlSrvProfilerFileSync = 0; |
|
62 TInt TheSqlSrvProfilerFileSetSize = 0; |
|
63 #endif |
|
64 |
|
65 /////////////////////////////////////////////////////////////////////////////////////// |
|
66 |
|
67 //Creates TPtrC object which points to the unicode presentation of aData. |
|
68 //aData argument is expected to point to UTF8 encoded, zero terminated string. |
|
69 //The function returns a TPtrC, non-zero terminated object pointing to the unicode presentation of aData. |
|
70 //If the length of the returned TPtrC object is 0 - it means that unicode conversion of aData failed, |
|
71 //because the aData is too long or is NULL. |
|
72 //Max allowed aData length is KMaxFileName (excluding terminating 0 character). |
|
73 static TPtrC ConvertToUtf16(const char *aData) |
|
74 { |
|
75 TPtrC ptr(0, 0); |
|
76 if(aData) |
|
77 { |
|
78 TInt len = mbstowcs(reinterpret_cast <wchar_t*> (TheFileName), aData, KMaxFileName + 1); |
|
79 //Check converted string length. If it is longer than KMaxFileName characters, then aData is too long. |
|
80 if(len > 0 && len <= KMaxFileName) |
|
81 { |
|
82 ptr.Set(TheFileName, len); |
|
83 } |
|
84 } |
|
85 return ptr; |
|
86 } |
|
87 |
|
88 /////////////////////////////////////////////////////////////////////////////////////// |
|
89 |
|
90 static void DeleteTestFiles() |
|
91 { |
|
92 sqlite3_close(TheDb2); |
|
93 sqlite3_close(TheDb1); |
|
94 |
|
95 TheFs.Delete(ConvertToUtf16(KDbName2)); |
|
96 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
97 TheFs.Delete(KContactsFile); |
|
98 } |
|
99 |
|
100 /////////////////////////////////////////////////////////////////////////////////////// |
|
101 /////////////////////////////////////////////////////////////////////////////////////// |
|
102 //Test macros and functions |
|
103 static void Check(TInt aValue, TInt aLine) |
|
104 { |
|
105 if(!aValue) |
|
106 { |
|
107 DeleteTestFiles(); |
|
108 TheTest(EFalse, aLine); |
|
109 } |
|
110 } |
|
111 static void Check(TInt aValue, TInt aExpected, TInt aLine) |
|
112 { |
|
113 if(aValue != aExpected) |
|
114 { |
|
115 DeleteTestFiles(); |
|
116 RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); |
|
117 TheTest(EFalse, aLine); |
|
118 } |
|
119 } |
|
120 #define TEST(arg) ::Check((arg), __LINE__) |
|
121 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) |
|
122 |
|
123 /////////////////////////////////////////////////////////////////////////////////////// |
|
124 |
|
125 static void CreatePrivateDirs() |
|
126 { |
|
127 RFs fs; |
|
128 TEST2(fs.Connect(), KErrNone); |
|
129 for(TInt i=0;i<('Z'-'A');++i) |
|
130 { |
|
131 fs.CreatePrivatePath(i); |
|
132 } |
|
133 fs.Close(); |
|
134 } |
|
135 |
|
136 /////////////////////////////////////////////////////////////////////////////////////// |
|
137 |
|
138 static void PrintConfig(const TDesC& aDbFilePath) |
|
139 { |
|
140 RDebug::Print(_L("================= Configuration ================\r\n")); |
|
141 RDebug::Print(_L("Cache page size %dK, pages %d, total %dK\r\n"), SQLITE_DEFAULT_PAGE_SIZE/1024, SQLITE_DEFAULT_CACHE_SIZE, SQLITE_DEFAULT_PAGE_SIZE * SQLITE_DEFAULT_CACHE_SIZE/1024); |
|
142 RDebug::Print(_L("Temp cache page size %dK, pages %d, total %dK\r\n"), SQLITE_DEFAULT_PAGE_SIZE/1024, SQLITE_DEFAULT_TEMP_CACHE_SIZE, SQLITE_DEFAULT_PAGE_SIZE * SQLITE_DEFAULT_TEMP_CACHE_SIZE/1024); |
|
143 _LIT(K1, "On"); |
|
144 _LIT(K2, "Off"); |
|
145 RDebug::Print(_L("Autovacuum: %S\r\n"), SQLITE_DEFAULT_AUTOVACUUM ? &K1 : &K2); |
|
146 #ifdef SQLITE_DEBUG |
|
147 RDebug::Print(_L("Debug: On\r\n")); |
|
148 #else |
|
149 RDebug::Print(_L("Debug: Off\r\n")); |
|
150 #endif |
|
151 RDebug::Print(_L("Db file: %S\r\n"), &aDbFilePath); |
|
152 RDebug::Print(_L("================================================\r\n")); |
|
153 } |
|
154 |
|
155 /////////////////////////////////////////////////////////////////////////////////////// |
|
156 |
|
157 static TInt callback(void */*NotUsed*/, TInt argc, char **argv, char **azColName) |
|
158 { |
|
159 TInt i; |
|
160 for(i=0; i<argc; i++) |
|
161 { |
|
162 TPtrC8 colName((const TUint8*)azColName[i]); |
|
163 TPtrC8 colVal((const TUint8*)(argv[i] ? argv[i] : "NULL")); |
|
164 TheBuf2.Copy(colName); |
|
165 TheBuf2.Append(_L(" = ")); |
|
166 TheBuf1.Copy(colVal); |
|
167 TheBuf2.Append(TheBuf1); |
|
168 RDebug::Print(_L("%S\r\n"), &TheBuf2); |
|
169 } |
|
170 RDebug::Print(_L("\n")); |
|
171 return 0; |
|
172 } |
|
173 |
|
174 static TInt Compare(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
175 { |
|
176 TPtrC8 ptr1((TUint8*)p1, size1); |
|
177 TPtrC8 ptr2((TUint8*)p2, size2); |
|
178 |
|
179 TInt res = ptr1.CompareF(ptr2); |
|
180 return res; |
|
181 } |
|
182 |
|
183 static TInt Compare2(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
184 { |
|
185 TPtrC8 ptr1((TUint8*)p1, size1); |
|
186 TPtrC8 ptr2((TUint8*)p2, size2); |
|
187 |
|
188 TInt res = -ptr1.Compare(ptr2); |
|
189 return res; |
|
190 } |
|
191 |
|
192 |
|
193 static void Func(sqlite3_context* ctx, TInt nCnt, sqlite3_value** pp) |
|
194 { |
|
195 for(TInt i=0;i<nCnt;++i) |
|
196 { |
|
197 TInt v = sqlite3_value_int(*pp++); |
|
198 v = v; |
|
199 } |
|
200 sqlite3_result_int(ctx, 564); |
|
201 } |
|
202 |
|
203 /////////////////////////////////////////////////////////////////////////////////////// |
|
204 |
|
205 //Create database, table, view, INSERT, SELECT, DELETE sql statements, register collations, |
|
206 //user defined functions, CREATE INDEX, CREATE VIEW sql statements, GROUP BY, HAVING, EXCEPT,... |
|
207 static void DoTests1() |
|
208 { |
|
209 char *zErrMsg = 0; |
|
210 TInt rc; |
|
211 |
|
212 rc = sqlite3_open(KDbName1, &TheDb1); |
|
213 if(rc) |
|
214 { |
|
215 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
216 RDebug::Print(_L("Can't open database, err %d, msg: %S\n"), rc, &p); |
|
217 TEST(0); |
|
218 } |
|
219 |
|
220 rc = sqlite3_create_collation(TheDb1, "Clt1", SQLITE_UTF8, NULL, &Compare); |
|
221 if(rc) |
|
222 { |
|
223 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
224 RDebug::Print(_L("Can't create collation, err %d, msg: %S\n"), rc, &p); |
|
225 TEST(0); |
|
226 } |
|
227 |
|
228 rc = sqlite3_create_collation(TheDb1, "Clt2", SQLITE_UTF8, NULL, &Compare2); |
|
229 if(rc) |
|
230 { |
|
231 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
232 RDebug::Print(_L("Can't create collation, err %d, msg: %S\n"), rc, &p); |
|
233 TEST(0); |
|
234 } |
|
235 |
|
236 rc = sqlite3_create_function(TheDb1, "Func", 2, SQLITE_UTF8, NULL, Func, NULL, NULL); |
|
237 if(rc) |
|
238 { |
|
239 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
240 RDebug::Print(_L("Can't create UDF, err %d, msg: %S\n"), rc, &p); |
|
241 TEST(0); |
|
242 } |
|
243 |
|
244 rc = sqlite3_exec(TheDb1, "\ |
|
245 BEGIN TRANSACTION;\ |
|
246 CREATE TABLE Pn(Id INTEGER PRIMARY KEY AUTOINCREMENT,\ |
|
247 Name TEXT NOT NULL,\ |
|
248 Surname TEXT NOT NULL COLLATE Clt1);\ |
|
249 CREATE INDEX PnSurname ON Pn(Surname);\ |
|
250 CREATE TABLE Addr(Id INTEGER PRIMARY KEY AUTOINCREMENT,\ |
|
251 PnId INTEGER,\ |
|
252 CityId INTEGER,\ |
|
253 Location TEXT DEFAULT 'address');\ |
|
254 CREATE INDEX AddrPnId ON Addr(PnId);\ |
|
255 CREATE INDEX AddrCityId ON Addr(CityId);\ |
|
256 CREATE TABLE City(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT Default 'None');\ |
|
257 CREATE TABLE Shop(Id INTEGER, Name TEXT);\ |
|
258 CREATE TABLE Sales(ShopId INTEGER, M MONEY, D TIMESTAMP, D1 DATE, T1 TIME);\ |
|
259 CREATE TRIGGER TrgPnDel BEFORE DELETE ON Pn \ |
|
260 BEGIN \ |
|
261 SELECT Func(2,8);\ |
|
262 SELECT CASE WHEN ((SELECT COUNT(*) FROM Addr WHERE Addr.PnId = old.Id) > 0) \ |
|
263 THEN RAISE (ABORT, 'Foreign key constraint violation!!!') \ |
|
264 END;\ |
|
265 END;\ |
|
266 CREATE VIEW V1 AS SELECT * FROM Pn;\ |
|
267 CREATE VIEW V2 AS SELECT * FROM Addr;\ |
|
268 CREATE VIEW V3 AS SELECT * FROM Sales;\ |
|
269 CREATE VIEW V4 AS SELECT * FROM Shop;\ |
|
270 COMMIT TRANSACTION;", callback, 0, &zErrMsg); |
|
271 |
|
272 if(rc != SQLITE_OK) |
|
273 { |
|
274 TPtrC p = ConvertToUtf16(zErrMsg); |
|
275 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
276 sqlite3_free(zErrMsg); |
|
277 TEST(0); |
|
278 } |
|
279 |
|
280 rc = sqlite3_exec(TheDb1, |
|
281 "BEGIN TRANSACTION;\ |
|
282 INSERT INTO Pn(Name, Surname) VALUES('Aaaa1', 'Aaaa2');\ |
|
283 INSERT INTO Pn(Name, Surname) VALUES('Bbbb1', 'Bbbb2');\ |
|
284 INSERT INTO Pn(Name, Surname) VALUES('Cccc1', 'Cccc2');\ |
|
285 INSERT INTO Pn(Name, Surname) VALUES('Dddd1', 'Dddd2');\ |
|
286 INSERT INTO City(Name) VALUES('London');\ |
|
287 INSERT INTO City(Name) VALUES('Manchester');\ |
|
288 INSERT INTO Addr(PnId, CityId, Location) SELECT Pn.Id, City.Id, 'Here' FROM Pn, City WHERE Pn.Surname = 'Cccc2' AND City.Name = 'London';\ |
|
289 INSERT INTO Addr(PnId, CityId, Location) SELECT Pn.Id, City.Id, 'There' FROM Pn, City WHERE Pn.Surname = 'Bbbb2' AND City.Name = 'Manchester';\ |
|
290 INSERT INTO Shop(Id, Name) VALUES(1, 'Shop-1');\ |
|
291 INSERT INTO Shop(Id, Name) VALUES(2, 'Shop-2');\ |
|
292 INSERT INTO Shop(Id, Name) VALUES(3, 'Shop-3');\ |
|
293 INSERT INTO Sales(ShopId, M, D, D1, T1) VALUES(1, 123.0, '2005-01-01', CURRENT_DATE, '12:34:17');\ |
|
294 INSERT INTO Sales(ShopId, M, D, D1, T1) VALUES(2, 100.0, '2005-01-01', '2005-01-27', '12:34:18');\ |
|
295 INSERT INTO Sales(ShopId, M, D, D1, T1) VALUES(2, 200.0, '2005-01-02', '2005-01-28', '12:34:19');\ |
|
296 INSERT INTO Sales(ShopId, M, D, D1, T1) VALUES(3, 200.0, '2005-01-03', '2005-01-29', '12:34:23');\ |
|
297 COMMIT TRANSACTION;", callback, 0, &zErrMsg); |
|
298 if(rc != SQLITE_OK) |
|
299 { |
|
300 TPtrC p = ConvertToUtf16(zErrMsg); |
|
301 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
302 sqlite3_free(zErrMsg); |
|
303 TEST(0); |
|
304 } |
|
305 |
|
306 rc = sqlite3_exec(TheDb1, "SELECT COUNT(*) FROM Shop", callback, 0, &zErrMsg); |
|
307 if(rc != SQLITE_OK) |
|
308 { |
|
309 TPtrC p = ConvertToUtf16(zErrMsg); |
|
310 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
311 sqlite3_free(zErrMsg); |
|
312 TEST(0); |
|
313 } |
|
314 |
|
315 for(TInt i=0;i<500;++i) |
|
316 { |
|
317 _LIT8(KSqlStmt, "INSERT INTO Shop(Id, Name) VALUES(%d, 'Shop-%d')\x0"); |
|
318 TheBuf3.Format(KSqlStmt, i+1, i+1); |
|
319 rc = sqlite3_exec(TheDb1, (const char*)TheBuf3.Ptr(), callback, 0, &zErrMsg); |
|
320 if(rc != SQLITE_OK) |
|
321 { |
|
322 TPtrC p = ConvertToUtf16(zErrMsg); |
|
323 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
324 sqlite3_free(zErrMsg); |
|
325 TEST(0); |
|
326 } |
|
327 } |
|
328 |
|
329 _LIT8(KSqlStmt2, "DELETE FROM Shop WHERE Id > 400\x0"); |
|
330 rc = sqlite3_exec(TheDb1, (const char*)KSqlStmt2().Ptr(), callback, 0, &zErrMsg); |
|
331 if(rc != SQLITE_OK) |
|
332 { |
|
333 TPtrC p = ConvertToUtf16(zErrMsg); |
|
334 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
335 sqlite3_free(zErrMsg); |
|
336 TEST(0); |
|
337 } |
|
338 |
|
339 _LIT8(KSqlStmt3, "SELECT COUNT(*) FROM Shop\x0"); |
|
340 rc = sqlite3_exec(TheDb1, (const char*)KSqlStmt3().Ptr(), callback, 0, &zErrMsg); |
|
341 if(rc != SQLITE_OK) |
|
342 { |
|
343 TPtrC p = ConvertToUtf16(zErrMsg); |
|
344 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
345 sqlite3_free(zErrMsg); |
|
346 TEST(0); |
|
347 } |
|
348 |
|
349 rc = sqlite3_exec(TheDb1, "SELECT Pn.Surname, Addr.Location, City.Name FROM Pn \ |
|
350 INNER JOIN Addr ON Pn.Id = Addr.PnId \ |
|
351 INNER JOIN City ON Addr.CityId = City.Id \ |
|
352 ORDER BY Surname COLLATE Clt2", callback, 0, &zErrMsg); |
|
353 if(rc != SQLITE_OK) |
|
354 { |
|
355 TPtrC p = ConvertToUtf16(zErrMsg); |
|
356 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
357 sqlite3_free(zErrMsg); |
|
358 TEST(0); |
|
359 } |
|
360 |
|
361 rc = sqlite3_exec(TheDb1, "SELECT * FROM Addr", callback, 0, &zErrMsg); |
|
362 if(rc != SQLITE_OK) |
|
363 { |
|
364 TPtrC p = ConvertToUtf16(zErrMsg); |
|
365 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
366 sqlite3_free(zErrMsg); |
|
367 TEST(0); |
|
368 } |
|
369 |
|
370 rc = sqlite3_exec(TheDb1, "SELECT * FROM Sales WHERE D1 > '2005-08-27'", callback, 0, &zErrMsg); |
|
371 if(rc != SQLITE_OK) |
|
372 { |
|
373 TPtrC p = ConvertToUtf16(zErrMsg); |
|
374 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
375 sqlite3_free(zErrMsg); |
|
376 TEST(0); |
|
377 } |
|
378 |
|
379 rc = sqlite3_exec(TheDb1, "SELECT V1.* FROM V1 EXCEPT SELECT V1.* FROM V1 WHERE V1.Id = 2", callback, 0, &zErrMsg); |
|
380 if(rc != SQLITE_OK) |
|
381 { |
|
382 TPtrC p = ConvertToUtf16(zErrMsg); |
|
383 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
384 sqlite3_free(zErrMsg); |
|
385 TEST(0); |
|
386 } |
|
387 |
|
388 rc = sqlite3_exec(TheDb1, "SELECT V3.D, SUM(V3.M) FROM V3 GROUP BY V3.D HAVING SUM(V3.M) > 210.0", callback, 0, &zErrMsg); |
|
389 if(rc != SQLITE_OK) |
|
390 { |
|
391 TPtrC p = ConvertToUtf16(zErrMsg); |
|
392 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
393 sqlite3_free(zErrMsg); |
|
394 TEST(0); |
|
395 } |
|
396 |
|
397 rc = sqlite3_exec(TheDb1, "SELECT V4.Name, SUM(V3.M) FROM V4, V3 WHERE V4.Id = V3.ShopId GROUP BY V4.Id", callback, 0, &zErrMsg); |
|
398 if(rc != SQLITE_OK) |
|
399 { |
|
400 TPtrC p = ConvertToUtf16(zErrMsg); |
|
401 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
402 sqlite3_free(zErrMsg); |
|
403 TEST(0); |
|
404 } |
|
405 |
|
406 sqlite3_close(TheDb1); |
|
407 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
408 } |
|
409 |
|
410 //Generic SQL tests. |
|
411 static void DoTests2() |
|
412 { |
|
413 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
414 |
|
415 char *zErrMsg = 0; |
|
416 TInt rc; |
|
417 |
|
418 rc = sqlite3_open(KDbName1, &TheDb1); |
|
419 if(rc != SQLITE_OK) |
|
420 { |
|
421 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
422 RDebug::Print(_L("Can't open database, err %d, msg: %S\n"), rc, &p); |
|
423 TEST(0); |
|
424 } |
|
425 |
|
426 rc = sqlite3_exec(TheDb1, "PRAGMA auto_vacuum = 1", callback, 0, &zErrMsg); |
|
427 if(rc != SQLITE_OK) |
|
428 { |
|
429 TPtrC p = ConvertToUtf16(zErrMsg); |
|
430 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
431 sqlite3_free(zErrMsg); |
|
432 TEST(0); |
|
433 } |
|
434 |
|
435 rc = sqlite3_exec(TheDb1, "\ |
|
436 BEGIN TRANSACTION;\ |
|
437 CREATE TABLE Shop(Id INTEGER, Name TEXT);\ |
|
438 CREATE INDEX ShopName ON Shop(Name);\ |
|
439 COMMIT TRANSACTION;", callback, 0, &zErrMsg); |
|
440 if(rc != SQLITE_OK) |
|
441 { |
|
442 TPtrC p = ConvertToUtf16(zErrMsg); |
|
443 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
444 sqlite3_free(zErrMsg); |
|
445 TEST(0); |
|
446 } |
|
447 |
|
448 rc = sqlite3_exec(TheDb1, "BEGIN TRANSACTION", callback, 0, &zErrMsg); |
|
449 if(rc != SQLITE_OK) |
|
450 { |
|
451 TPtrC p = ConvertToUtf16(zErrMsg); |
|
452 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
453 sqlite3_free(zErrMsg); |
|
454 TEST(0); |
|
455 } |
|
456 |
|
457 for(TInt i=0;i<1000;++i) |
|
458 { |
|
459 _LIT8(KSqlStmt, "INSERT INTO Shop(Id, Name) VALUES(%d, 'Shop-%d')\x0"); |
|
460 TheBuf3.Format(KSqlStmt, i, i); |
|
461 rc = sqlite3_exec(TheDb1, (const char*)TheBuf3.Ptr(), callback, 0, &zErrMsg); |
|
462 if(rc != SQLITE_OK) |
|
463 { |
|
464 TPtrC p = ConvertToUtf16(zErrMsg); |
|
465 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
466 sqlite3_free(zErrMsg); |
|
467 TEST(0); |
|
468 } |
|
469 } |
|
470 |
|
471 rc = sqlite3_exec(TheDb1, "COMMIT TRANSACTION", callback, 0, &zErrMsg); |
|
472 if(rc != SQLITE_OK) |
|
473 { |
|
474 TPtrC p = ConvertToUtf16(zErrMsg); |
|
475 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
476 sqlite3_free(zErrMsg); |
|
477 TEST(0); |
|
478 } |
|
479 |
|
480 rc = sqlite3_exec(TheDb1, "SELECT COUNT(*) FROM Shop", callback, 0, &zErrMsg); |
|
481 if(rc != SQLITE_OK) |
|
482 { |
|
483 TPtrC p = ConvertToUtf16(zErrMsg); |
|
484 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
485 sqlite3_free(zErrMsg); |
|
486 TEST(0); |
|
487 } |
|
488 |
|
489 rc = sqlite3_exec(TheDb1, "BEGIN TRANSACTION", callback, 0, &zErrMsg); |
|
490 if(rc != SQLITE_OK) |
|
491 { |
|
492 TPtrC p = ConvertToUtf16(zErrMsg); |
|
493 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
494 sqlite3_free(zErrMsg); |
|
495 TEST(0); |
|
496 } |
|
497 |
|
498 rc = sqlite3_exec(TheDb1, "DELETE FROM Shop WHERE Id > 100", callback, 0, &zErrMsg); |
|
499 if(rc != SQLITE_OK) |
|
500 { |
|
501 TPtrC p = ConvertToUtf16(zErrMsg); |
|
502 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
503 sqlite3_free(zErrMsg); |
|
504 TEST(0); |
|
505 } |
|
506 |
|
507 rc = sqlite3_exec(TheDb1, "COMMIT TRANSACTION", callback, 0, &zErrMsg); |
|
508 if(rc != SQLITE_OK) |
|
509 { |
|
510 TPtrC p = ConvertToUtf16(zErrMsg); |
|
511 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
512 sqlite3_free(zErrMsg); |
|
513 TEST(0); |
|
514 } |
|
515 |
|
516 rc = sqlite3_exec(TheDb1, "SELECT COUNT(*) FROM Shop", callback, 0, &zErrMsg); |
|
517 if(rc != SQLITE_OK) |
|
518 { |
|
519 TPtrC p = ConvertToUtf16(zErrMsg); |
|
520 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
521 sqlite3_free(zErrMsg); |
|
522 TEST(0); |
|
523 } |
|
524 |
|
525 sqlite3_close(TheDb1); |
|
526 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
527 } |
|
528 |
|
529 //Accented column names test |
|
530 static void AccentedColumnNamesTestL() |
|
531 { |
|
532 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
533 |
|
534 //Open database |
|
535 TPtrC tmp = ConvertToUtf16(KDbName1); |
|
536 TBuf<KMaxFileName + 1> fname; |
|
537 fname.Copy(tmp); |
|
538 TInt rc = sqlite3_open16(fname.PtrZ(), &TheDb1);//!!!!16-bit encoding!!!!! |
|
539 if(rc != SQLITE_OK) |
|
540 { |
|
541 TPtrC p = ConvertToUtf16(sqlite3_errmsg(TheDb1)); |
|
542 RDebug::Print(_L("Can't open database, err %d, msg: %S\n"), rc, &p); |
|
543 TEST(0); |
|
544 } |
|
545 |
|
546 //Create table |
|
547 _LIT(KSqlStrZ, "CREATE TABLE abc(col_\u00C4 integer, col_A text)\0"); |
|
548 // _LIT(KSqlStrZ, "CREATE TABLE abc(col_a integer, col_A text)\0"); |
|
549 // _LIT(KSqlStrZ, "CREATE TABLE abc(col_Ä integer, col_ä text)\0"); |
|
550 // _LIT(KSqlStrZ, "CREATE TABLE abc(col_Ä integer, col_A\x308 text)\0"); |
|
551 sqlite3_stmt* stmtHandle = NULL; |
|
552 const void* stmtTailZ = NULL; |
|
553 rc = sqlite3_prepare16_v2(TheDb1, KSqlStrZ().Ptr(), -1, &stmtHandle, &stmtTailZ); |
|
554 if(rc != SQLITE_OK) |
|
555 { |
|
556 const void* errMsgZ = sqlite3_errmsg16(TheDb1); |
|
557 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
558 RDebug::Print(_L("'sqlite3_prepare16_v2()' failed, err %d, error msg: \"%S\"\r\n"), rc, &msg); |
|
559 TEST(0); |
|
560 } |
|
561 rc = sqlite3_step(stmtHandle); |
|
562 TEST(rc == SQLITE_DONE); |
|
563 |
|
564 sqlite3_finalize(stmtHandle); |
|
565 stmtHandle = NULL; |
|
566 |
|
567 //Select from the table |
|
568 _LIT(KSqlStrZ2, "SELECT * FROM abc WHERE :prm_\u00C4 = col_\u00C4 and :prm_\u00E4 = col_A and :prm_A = col_A and :prm_a = col_\u00C4\0"); |
|
569 rc = sqlite3_prepare16_v2(TheDb1, KSqlStrZ2().Ptr(), -1, &stmtHandle, &stmtTailZ); |
|
570 if(rc != SQLITE_OK) |
|
571 { |
|
572 const void* errMsgZ = sqlite3_errmsg16(TheDb1); |
|
573 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
574 RDebug::Print(_L("'sqlite3_prepare16_v2()' failed, err %d, error msg: \"%S\"\r\n"), rc, &msg); |
|
575 TEST(0); |
|
576 } |
|
577 |
|
578 //parameter checks |
|
579 TBuf<16> prmNames[5]; |
|
580 TInt prmCount = sqlite3_bind_parameter_count(stmtHandle); |
|
581 for(TInt i=1;i<=prmCount;++i) |
|
582 { |
|
583 const char* prmNameZ = sqlite3_bind_parameter_name(stmtHandle, i); |
|
584 TPtrC8 name8(reinterpret_cast <const TUint8*> (prmNameZ), strlen(prmNameZ)); |
|
585 HBufC* name = CnvUtfConverter::ConvertToUnicodeFromUtf8L(name8); |
|
586 prmNames[i] = *name; |
|
587 delete name; |
|
588 } |
|
589 TInt prmIndex0_1 = sqlite3_bind_parameter_index(stmtHandle, ":prm_Ä"); |
|
590 prmIndex0_1 = prmIndex0_1; |
|
591 TInt prmIndex1_1 = sqlite3_bind_parameter_index(stmtHandle, ":prm_ä"); |
|
592 prmIndex1_1 = prmIndex1_1; |
|
593 TInt prmIndex2_1 = sqlite3_bind_parameter_index(stmtHandle, ":prm_A"); |
|
594 prmIndex2_1 = prmIndex2_1; |
|
595 TInt prmIndex3_1 = sqlite3_bind_parameter_index(stmtHandle, ":prm_a"); |
|
596 prmIndex3_1 = prmIndex3_1; |
|
597 |
|
598 TBuf8<16> name8; |
|
599 |
|
600 HBufC8* name = CnvUtfConverter::ConvertFromUnicodeToUtf8L(prmNames[1]); |
|
601 name8 = *name; |
|
602 delete name; |
|
603 TInt prmIndex0_2 = sqlite3_bind_parameter_index(stmtHandle, (const char*)name8.PtrZ()); |
|
604 prmIndex0_2 = prmIndex0_2; |
|
605 |
|
606 name = CnvUtfConverter::ConvertFromUnicodeToUtf8L(prmNames[2]); |
|
607 name8 = *name; |
|
608 delete name; |
|
609 TInt prmIndex1_2 = sqlite3_bind_parameter_index(stmtHandle, (const char*)name8.PtrZ()); |
|
610 prmIndex1_2 = prmIndex1_2; |
|
611 |
|
612 name = CnvUtfConverter::ConvertFromUnicodeToUtf8L(prmNames[3]); |
|
613 name8 = *name; |
|
614 delete name; |
|
615 TInt prmIndex2_2 = sqlite3_bind_parameter_index(stmtHandle, (const char*)name8.PtrZ()); |
|
616 prmIndex2_2 = prmIndex2_2; |
|
617 |
|
618 name = CnvUtfConverter::ConvertFromUnicodeToUtf8L(prmNames[4]); |
|
619 name8 = *name; |
|
620 delete name; |
|
621 TInt prmIndex3_2 = sqlite3_bind_parameter_index(stmtHandle, (const char*)name8.PtrZ()); |
|
622 prmIndex3_2 = prmIndex3_2; |
|
623 |
|
624 //Column checks |
|
625 TPtrC colName1(_L("col_\u00C4")); |
|
626 TPtrC colName2(_L("col_A")); |
|
627 |
|
628 const void* p = sqlite3_column_name16(stmtHandle, 0); |
|
629 TPtrC pp1((const TUint16*)p, wcslen(reinterpret_cast <const wchar_t*> (p))); |
|
630 TEST(colName1 == pp1); |
|
631 |
|
632 p = sqlite3_column_name16(stmtHandle, 1); |
|
633 TPtrC pp2((const TUint16*)p, wcslen(reinterpret_cast <const wchar_t*> (p))); |
|
634 TEST(colName2 == pp2); |
|
635 |
|
636 sqlite3_finalize(stmtHandle); |
|
637 |
|
638 sqlite3_close(TheDb1); |
|
639 TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
640 } |
|
641 |
|
642 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
643 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
644 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
645 ////////////// "Add Contacts" test case //////////////////////////// |
|
646 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
647 |
|
648 //Read SQL file - 8-bit, zero-terminated string |
|
649 static char* ReadSQL2(const TDesC& aSqlFileName) |
|
650 { |
|
651 RFile file; |
|
652 TEST2(file.Open(TheFs, aSqlFileName, EFileRead), KErrNone); |
|
653 |
|
654 TInt size = 0; |
|
655 TEST2(file.Size(size), KErrNone); |
|
656 |
|
657 char* sql = new char [size + 1]; |
|
658 TEST(sql != NULL); |
|
659 |
|
660 TPtr8 ptr((TUint8*)sql, size + 1); |
|
661 TEST2(file.Read(ptr, size), KErrNone); |
|
662 *(sql + size) = 0; |
|
663 |
|
664 file.Close(); |
|
665 return sql; |
|
666 } |
|
667 |
|
668 //Read SQL file - 16-bit, zero-terminated string |
|
669 static HBufC* ReadSQL16(const TDesC& aSqlFileName) |
|
670 { |
|
671 RFile file; |
|
672 TEST2(file.Open(TheFs, aSqlFileName, EFileRead), KErrNone); |
|
673 |
|
674 TInt size = 0; |
|
675 TEST2(file.Size(size), KErrNone); |
|
676 |
|
677 char* sql = new char [size]; |
|
678 TEST(sql != NULL); |
|
679 TPtr8 ptr((TUint8*)sql, size); |
|
680 TEST2(file.Read(ptr, size), KErrNone); |
|
681 |
|
682 HBufC* sql16 = HBufC::New(size + 1); |
|
683 TEST(sql16 != NULL); |
|
684 TPtr16 ptr16 = sql16->Des(); |
|
685 ptr16.Copy(ptr); |
|
686 ptr16.Append(TChar(0)); |
|
687 |
|
688 delete [] sql; |
|
689 file.Close(); |
|
690 return sql16; |
|
691 } |
|
692 |
|
693 //Prints file size in bytes |
|
694 static void PrintFileSize(const TDesC& aPath) |
|
695 { |
|
696 RFile file; |
|
697 TEST2(file.Open(TheFs, aPath, EFileRead), KErrNone); |
|
698 TInt size = 0; |
|
699 TEST2(file.Size(size), KErrNone); |
|
700 file.Close(); |
|
701 RDebug::Print(_L("File \"%S\", size: %d\r\n"), &aPath, size); |
|
702 } |
|
703 |
|
704 //Executes 8-bit SQL statement |
|
705 static void ExecSql(sqlite3* aDbHandle, const char* aSqlStmt, const TDesC& aMsg) |
|
706 { |
|
707 TEST(aDbHandle != NULL); |
|
708 TEST(aSqlStmt != NULL); |
|
709 |
|
710 char* errMsg = NULL; |
|
711 TTime t1; |
|
712 t1.UniversalTime(); |
|
713 TInt rc = sqlite3_exec(aDbHandle, aSqlStmt, callback, 0, &errMsg); |
|
714 if(rc != SQLITE_OK) |
|
715 { |
|
716 TPtrC8 ptr8((const TUint8*)errMsg, strlen(errMsg)); |
|
717 TheBuf1.Copy(ptr8); |
|
718 RDebug::Print(_L("'sqlite3_exec()' failed, err %d, error msg: \"%S\"\t\n"), rc, &TheBuf1); |
|
719 TEST(0); |
|
720 } |
|
721 TTime t2; |
|
722 t2.UniversalTime(); |
|
723 TTimeIntervalMicroSeconds diffTime = t2.MicroSecondsFrom(t1); |
|
724 diffTime = diffTime.Int64() / 1000; |
|
725 RDebug::Print(_L("%S, time: %d ms\r\n"), &aMsg, (TInt)diffTime.Int64()); |
|
726 } |
|
727 |
|
728 //This function searches aString argument for ';' occurences. |
|
729 //Every time when it finds a ';' character, the function places a 0 right after the ';' and |
|
730 //tests the just created, zero-terminated substring if it is a comlpete SQL statement. |
|
731 //If it is a SQL statement, the function returns it and modifies aString argument to point right after the found |
|
732 //SQL string. If it is not SQL statement, the function will continue the searching. |
|
733 //If there is no ';' inside aString argument, the function returns the same string as a return result and |
|
734 //modifies aString argument - sets it to TPtr(NULL, 0, 0). |
|
735 // |
|
736 //The function expects aString argument to be zero-terminated. |
|
737 static TPtrC GetFirstSqlStmt(TPtr& aString) |
|
738 { |
|
739 const TChar KDelimitier(';'); |
|
740 TPtr str(const_cast <TUint16*> (aString.Ptr()), aString.Length(), aString.Length()); |
|
741 TInt afterDelimitierPos = 0; |
|
742 TInt pos; |
|
743 while((pos = str.Locate(KDelimitier) + 1) > 0 && pos < str.Length()) |
|
744 { |
|
745 //There is a possibility that the string which terminates with the found ';' is SQL statement. |
|
746 //Zero terminate the string placing a zero right after ';' character and test it using sqlite3_complete16() |
|
747 //call. If it is not SQL string, restore the original character and continue searching. |
|
748 afterDelimitierPos += pos; |
|
749 TChar ch = aString[afterDelimitierPos]; |
|
750 aString[afterDelimitierPos] = 0; |
|
751 TInt res = sqlite3_complete16(aString.Ptr()); |
|
752 aString[afterDelimitierPos] = ch; |
|
753 if(res) |
|
754 { |
|
755 str.Set(const_cast <TUint16*> (aString.Ptr()), afterDelimitierPos, afterDelimitierPos); |
|
756 //Replace the found ';' character with 0. |
|
757 str[afterDelimitierPos - 1] = 0; |
|
758 aString.Set(const_cast <TUint16*> (aString.Ptr()) + afterDelimitierPos, aString.Length() - afterDelimitierPos, aString.Length() - afterDelimitierPos); |
|
759 return str; |
|
760 } |
|
761 str.Set(const_cast <TUint16*> (str.Ptr()) + pos, str.Length() - pos, str.Length() - pos); |
|
762 } |
|
763 //aString argument does not contain valid SQL statement or there is no ';' character inside aString. |
|
764 //Set aString to TPtr(NULL, 0, 0) and return the original string. |
|
765 aString.Set(NULL, 0, 0); |
|
766 return str; |
|
767 } |
|
768 |
|
769 //Executes 16-bit SQL statement |
|
770 static void ExecSql16(sqlite3* aDbHandle, TDes& aSqlStmtZ, const TDesC& aMsg) |
|
771 { |
|
772 TEST(aDbHandle != NULL); |
|
773 |
|
774 TTime t1; |
|
775 t1.UniversalTime(); |
|
776 |
|
777 TPtr sqlLeftZ(const_cast <TUint16*> (aSqlStmtZ.Ptr()), aSqlStmtZ.Length(), aSqlStmtZ.Length()); |
|
778 while(sqlLeftZ.Length() > 0) |
|
779 { |
|
780 TPtrC sql = GetFirstSqlStmt(sqlLeftZ); |
|
781 sqlite3_stmt* stmtHandle = NULL; |
|
782 const void* stmtTailZ = NULL; |
|
783 TInt err = sqlite3_prepare16_v2(aDbHandle, sql.Ptr(), -1, &stmtHandle, &stmtTailZ); |
|
784 __ASSERT_ALWAYS(!stmtTailZ || User::StringLength((const TUint16*)stmtTailZ) == 0, User::Invariant()); |
|
785 if(stmtHandle) |
|
786 { |
|
787 if(err == SQLITE_OK) |
|
788 { |
|
789 while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) |
|
790 { |
|
791 } |
|
792 } |
|
793 sqlite3_finalize(stmtHandle); |
|
794 } |
|
795 if(err != SQLITE_DONE && err != SQLITE_OK) |
|
796 { |
|
797 const void* errMsgZ = sqlite3_errmsg16(aDbHandle); |
|
798 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
799 RDebug::Print(_L("'sqlite3_exec16()' failed, err %d, error msg: \"%S\"\t\n"), err, &msg); |
|
800 TEST(0); |
|
801 } |
|
802 } |
|
803 TTime t2; |
|
804 t2.UniversalTime(); |
|
805 TTimeIntervalMicroSeconds diffTime = t2.MicroSecondsFrom(t1); |
|
806 diffTime = diffTime.Int64() / 1000; |
|
807 RDebug::Print(_L("%S, time: %d ms\r\n"), &aMsg, (TInt)diffTime.Int64()); |
|
808 } |
|
809 |
|
810 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
811 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
812 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
813 ////////////// "Search" test case //////////////////////////// |
|
814 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
815 |
|
816 struct TPnName |
|
817 { |
|
818 TPnName(const TDesC8& aFirstName, const TDesC8& aSurname) : |
|
819 iFirstName(aFirstName), |
|
820 iSurname(aSurname) |
|
821 { |
|
822 } |
|
823 const TPtrC8 iFirstName; |
|
824 const TPtrC8 iSurname; |
|
825 }; |
|
826 |
|
827 const TInt KNamesCnt = 100; |
|
828 |
|
829 const TPnName KNames[KNamesCnt] = |
|
830 { |
|
831 TPnName(_L8("Kauh"), _L8("Mollel")), |
|
832 TPnName(_L8("Be"), _L8("Balcalertthawnd")), |
|
833 TPnName(_L8("Joba"), _L8("Hah")), |
|
834 TPnName(_L8("Mal"), _L8("Sinianna")), |
|
835 TPnName(_L8("Alip"), _L8("Hanittrinke")), |
|
836 TPnName(_L8("Ris"), _L8("Aba")), |
|
837 TPnName(_L8("Nirindrilo"), _L8("Oangah")), |
|
838 TPnName(_L8("An"), _L8("Mck")), |
|
839 TPnName(_L8("Ris"), _L8("Jat")), |
|
840 TPnName(_L8("Ja"), _L8("R")), |
|
841 TPnName(_L8("Pary"), _L8("Sawngethwnes")), |
|
842 TPnName(_L8("Main"), _L8("Stonstc")), |
|
843 TPnName(_L8("Joldan"), _L8("Misonialonss")), |
|
844 TPnName(_L8("Ja"), _L8("Beetth")), |
|
845 TPnName(_L8("An"), _L8("Magill")), |
|
846 TPnName(_L8("Ste"), _L8("Hakegstolbebilance")), |
|
847 TPnName(_L8("Laelefattal"), _L8("Bume")), |
|
848 TPnName(_L8("Anortoausl"), _L8("Kenoonssssoninals")), |
|
849 TPnName(_L8("Sthnill"), _L8("Huere")), |
|
850 TPnName(_L8("Elatandy"), _L8("Miadhelbi")), |
|
851 TPnName(_L8("Nevieohageridik"), _L8("Baronirgeriallyemo")), |
|
852 TPnName(_L8("Dertrry"), _L8("Miches")), |
|
853 TPnName(_L8("Tan-"), _L8("Sonagutlly")), |
|
854 TPnName(_L8("Mazianer"), _L8("Wi")), |
|
855 TPnName(_L8("Kesadrin"), _L8("Swixohar")), |
|
856 TPnName(_L8("Juhnn"), _L8("Vezuins")), |
|
857 TPnName(_L8("Geri"), _L8("Okun-Mamar")), |
|
858 TPnName(_L8("Jol"), _L8("Hadir")), |
|
859 TPnName(_L8("Lon"), _L8("Fonernginire")), |
|
860 TPnName(_L8("Brrk"), _L8("El")), |
|
861 TPnName(_L8("So"), _L8("Thanas")), |
|
862 TPnName(_L8("Timon"), _L8("Matarol")), |
|
863 TPnName(_L8("Clicartif"), _L8("Sandhinth")), |
|
864 TPnName(_L8("Dan"), _L8("Brl")), |
|
865 TPnName(_L8("An"), _L8("Danss")), |
|
866 TPnName(_L8("Y"), _L8("Gianstes")), |
|
867 TPnName(_L8("Gralilas"), _L8("Beny")), |
|
868 TPnName(_L8("Vamean"), _L8("Matesstel")), |
|
869 TPnName(_L8("Ch"), _L8("Inrinez")), |
|
870 TPnName(_L8("Ra"), _L8("Lusieing")), |
|
871 TPnName(_L8("Gerik"), _L8("Mawoshar")), |
|
872 TPnName(_L8("Nobrd"), _L8("Kerokilirtsoug")), |
|
873 TPnName(_L8("Norichnik"), _L8("Balmo")), |
|
874 TPnName(_L8("Anddra"), _L8("Fit")), |
|
875 TPnName(_L8("Maily"), _L8("Tanyerohetsphinbr")), |
|
876 TPnName(_L8("Frsa"), _L8("Huntorrenerkh")), |
|
877 TPnName(_L8("Gi"), _L8("Spandaveees")), |
|
878 TPnName(_L8("Jollminenipaninderal"), _L8("Vartzury")), |
|
879 TPnName(_L8("Ankshr"), _L8("Terawloleral")), |
|
880 TPnName(_L8("An"), _L8("La")), |
|
881 TPnName(_L8("Ma"), _L8("Brnd")), |
|
882 TPnName(_L8("Sonerdalmon"), _L8("Bo")), |
|
883 TPnName(_L8("Nis"), _L8("Tapeworrt")), |
|
884 TPnName(_L8("Shand"), _L8("Hacllik")), |
|
885 TPnName(_L8("San"), _L8("Sh")), |
|
886 TPnName(_L8("Mico"), _L8("Javiaros")), |
|
887 TPnName(_L8("Hub"), _L8("Warey")), |
|
888 TPnName(_L8("Mambew"), _L8("Maw")), |
|
889 TPnName(_L8("Honik"), _L8("Fantscerstetoringu")), |
|
890 TPnName(_L8("Da"), _L8("Saneelur")), |
|
891 TPnName(_L8("Aberecalahayondorttelin"), _L8("Futtesesoxok")), |
|
892 TPnName(_L8("Dor"), _L8("Lelek")), |
|
893 TPnName(_L8("Matin"), _L8("Fure")), |
|
894 TPnName(_L8("Niasietolf"), _L8("Jonones")), |
|
895 TPnName(_L8("Das"), _L8("Hoeonds")), |
|
896 TPnName(_L8("Anchn"), _L8("Svss")), |
|
897 TPnName(_L8("Dor"), _L8("Bolunatrk")), |
|
898 TPnName(_L8("Casah"), _L8("Brilllundonsssoug")), |
|
899 TPnName(_L8("Iapew"), _L8("Bagukak")), |
|
900 TPnName(_L8("Lieni"), _L8("MoncNicel")), |
|
901 TPnName(_L8("Adewalyary"), _L8("Buradesorobbrerans")), |
|
902 TPnName(_L8("Tos"), _L8("Gis")), |
|
903 TPnName(_L8("Vi"), _L8("Berk")), |
|
904 TPnName(_L8("Jorya"), _L8("upmarone")), |
|
905 TPnName(_L8("Iatew"), _L8("Hend")), |
|
906 TPnName(_L8("Liag"), _L8("Brsmall")), |
|
907 TPnName(_L8("Al"), _L8("Spahay")), |
|
908 TPnName(_L8("El"), _L8("Sy")), |
|
909 TPnName(_L8("Pary"), _L8("Trl")), |
|
910 TPnName(_L8("Br"), _L8("Usouroneis")), |
|
911 TPnName(_L8("Sirnilly"), _L8("Olay")), |
|
912 TPnName(_L8("Fell"), _L8("Bouphies")), |
|
913 TPnName(_L8("Man"), _L8("Haz")), |
|
914 TPnName(_L8("Dare"), _L8("Was")), |
|
915 TPnName(_L8("Fahnahopephrtex"), _L8("Gat")), |
|
916 TPnName(_L8("Har"), _L8("Handfffebinneickiasse")), |
|
917 TPnName(_L8("Gerlai"), _L8("Boravirg")), |
|
918 TPnName(_L8("Miss"), _L8("Us")), |
|
919 TPnName(_L8("Caushatattoatot"), _L8("Wes")), |
|
920 TPnName(_L8("Eizicay"), _L8("Gunbss")), |
|
921 TPnName(_L8("Pan"), _L8("Hilesertatickesobss-")), |
|
922 TPnName(_L8("Anaw"), _L8("Mangar")), |
|
923 TPnName(_L8("Korba"), _L8("Siansolan")), |
|
924 TPnName(_L8("Darl"), _L8("Haginijelso")), |
|
925 TPnName(_L8("Ral"), _L8("Veddddkisocackeluisowowone")), |
|
926 TPnName(_L8("La"), _L8("Wawethl")), |
|
927 TPnName(_L8("Y"), _L8("Wisonkend")), |
|
928 TPnName(_L8("Evimiat"), _L8("JondepssooncClille")), |
|
929 TPnName(_L8("Rin"), _L8("DulatoliacKark")), |
|
930 TPnName(_L8("Shegeiew"), _L8("Ass")) |
|
931 }; |
|
932 |
|
933 ///////////////////////////////////////////////////////////// |
|
934 // 16-bit strings |
|
935 ///////////////////////////////////////////////////////////// |
|
936 |
|
937 static TInt CmpF16(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
938 { |
|
939 ++TheCmpFCallCnt; |
|
940 |
|
941 TPtrC16 ptr1((TUint16*)p1, size1/2); |
|
942 TPtrC16 ptr2((TUint16*)p2, size2/2); |
|
943 |
|
944 TInt res = ptr1.CompareF(ptr2); |
|
945 return res; |
|
946 } |
|
947 |
|
948 static TInt CmpC16(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
949 { |
|
950 ++TheCmpCCallCnt; |
|
951 |
|
952 TPtrC16 ptr1((TUint16*)p1, size1/2); |
|
953 TPtrC16 ptr2((TUint16*)p2, size2/2); |
|
954 TInt res = ptr1.CompareC(ptr2); |
|
955 return res; |
|
956 } |
|
957 |
|
958 static void SearchDbTest16(const TDesC& aDbFilePath) |
|
959 { |
|
960 TheFs.Delete(aDbFilePath); |
|
961 |
|
962 TBuf<KMaxFileName + 1> fname; |
|
963 fname.Copy(aDbFilePath); |
|
964 //Open database |
|
965 RDebug::Print(_L("Open database\r\n")); |
|
966 sqlite3 *dbHandle = NULL; |
|
967 TInt rc = sqlite3_open16(fname.PtrZ(), &dbHandle);//!!!!16-bit encoding!!!!! |
|
968 if(rc != SQLITE_OK) |
|
969 { |
|
970 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
971 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
972 RDebug::Print(_L("'sqlite3_open()' failed, file %S, err %d, error msg: \"%S\"\t\n"), &aDbFilePath, rc, &msg); |
|
973 TEST(0); |
|
974 } |
|
975 TEST(dbHandle != NULL); |
|
976 //Create "CompareF" collation |
|
977 RDebug::Print(_L("Create \"CompareF\" collation\r\n")); |
|
978 _LIT(KCmpF, "CmpF16\x0"); |
|
979 rc = sqlite3_create_collation16(dbHandle, (const char*)(KCmpF().Ptr()), SQLITE_UTF16 | SQLITE_UTF16_ALIGNED, NULL, &CmpF16); |
|
980 if(rc) |
|
981 { |
|
982 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
983 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
984 RDebug::Print(_L("Err=%S\r\n"), &msg); |
|
985 TEST(0); |
|
986 } |
|
987 //Create "CompareC" collation |
|
988 RDebug::Print(_L("Create \"CompareC\" collation\r\n")); |
|
989 _LIT(KCmpC, "CmpC16\x0"); |
|
990 rc = sqlite3_create_collation16(dbHandle, (const char*)(KCmpC().Ptr()), SQLITE_UTF16 | SQLITE_UTF16_ALIGNED, NULL, &CmpC16); |
|
991 if(rc) |
|
992 { |
|
993 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
994 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
995 RDebug::Print(_L("Err=%S\r\n"), &msg); |
|
996 TEST(0); |
|
997 } |
|
998 //Create database schema |
|
999 TheCmpFCallCnt = TheCmpCCallCnt = 0; |
|
1000 RDebug::Print(_L("Create database schema\r\n")); |
|
1001 HBufC16* createSqlZ = ReadSQL16(_L("z:\\test\\contacts_schema_to_vendors.sql")); |
|
1002 TPtr sql = createSqlZ->Des(); |
|
1003 ExecSql16(dbHandle, sql, _L("Create schema")); |
|
1004 delete createSqlZ; |
|
1005 RDebug::Print(_L("CmpF() call cnt %d, CmpC() call cnt %d\r\n"), TheCmpFCallCnt, TheCmpCCallCnt); |
|
1006 //Add 1001 "simple" contacts |
|
1007 TheCmpFCallCnt = TheCmpCCallCnt = 0; |
|
1008 RDebug::Print(_L("Add 1001 \"simple\" contacts\r\n")); |
|
1009 HBufC16* addSqlZ = ReadSQL16(KSimpleContactsSqlFile); |
|
1010 RDebug::Print(_L("--\r\n")); |
|
1011 sql.Set(addSqlZ->Des()); |
|
1012 ExecSql16(dbHandle, sql, _L("Add simple contacts")); |
|
1013 delete addSqlZ; |
|
1014 RDebug::Print(_L("CmpF() call cnt %d, CmpC() call cnt %d\r\n"), TheCmpFCallCnt, TheCmpCCallCnt); |
|
1015 //Print the number of records |
|
1016 RDebug::Print(_L("Print the number of records\r\n")); |
|
1017 TBuf<40> testSql(_L("SELECT COUNT(*) FROM CONTACTS")); |
|
1018 testSql.Append(TChar(0)); |
|
1019 ExecSql16(dbHandle, testSql, _L("--")); |
|
1020 |
|
1021 //Create index: "First name, Last name" |
|
1022 TheCmpFCallCnt = TheCmpCCallCnt = 0; |
|
1023 RDebug::Print(_L("Create index: \"First name, Last name\"\r\n")); |
|
1024 TBuf<100> createIndexStmt(_L("CREATE INDEX Idx1 ON identitytable(cm_firstname COLLATE CmpC16, cm_lastname COLLATE CmpC16)")); |
|
1025 createIndexStmt.Append(TChar(0)); |
|
1026 ExecSql16(dbHandle, createIndexStmt, _L("Create index")); |
|
1027 RDebug::Print(_L("CmpF() call cnt %d, CmpC() call cnt %d\r\n"), TheCmpFCallCnt, TheCmpCCallCnt); |
|
1028 |
|
1029 RDebug::Print(_L("Close database\r\n")); |
|
1030 sqlite3_close(dbHandle); |
|
1031 |
|
1032 PrintFileSize(aDbFilePath); |
|
1033 } |
|
1034 |
|
1035 ///////////////////////////////////////////////////////////// |
|
1036 // 8-bit strings |
|
1037 ///////////////////////////////////////////////////////////// |
|
1038 |
|
1039 static TInt CmpF8(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
1040 { |
|
1041 ++TheCmpFCallCnt; |
|
1042 TPtrC8 ptr1((TUint8*)p1, size1); |
|
1043 TPtrC8 ptr2((TUint8*)p2, size2); |
|
1044 |
|
1045 TInt res = ptr1.CompareF(ptr2); |
|
1046 return res; |
|
1047 } |
|
1048 |
|
1049 static TInt CmpC8(void*, TInt size1, const void* p1, TInt size2, const void* p2) |
|
1050 { |
|
1051 TPtrC8 ptr1((TUint8*)p1, size1); |
|
1052 TPtrC8 ptr2((TUint8*)p2, size2); |
|
1053 TInt res = ptr1.CompareC(ptr2); |
|
1054 return res; |
|
1055 } |
|
1056 |
|
1057 static void SearchDbTest8(const TDesC& aDbFilePath, const TDesC& aAddContactsFile, const TDesC& aMsg) |
|
1058 { |
|
1059 TheFs.Delete(aDbFilePath); |
|
1060 |
|
1061 TBuf8<KMaxFileName + 1> fname; |
|
1062 fname.Copy(aDbFilePath); |
|
1063 |
|
1064 RDebug::Print(_L("%S\r\n"), &aMsg); |
|
1065 RDebug::Print(_L("Open database\r\n")); |
|
1066 sqlite3 *dbHandle = NULL; |
|
1067 TInt rc = sqlite3_open((const char*)fname.PtrZ(), &dbHandle); |
|
1068 if(rc != SQLITE_OK) |
|
1069 { |
|
1070 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
1071 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
1072 RDebug::Print(_L("'sqlite3_open()' failed, file %S, err %d, error msg: \"%S\"\r\n"), &aDbFilePath, rc, &msg); |
|
1073 TEST(0); |
|
1074 } |
|
1075 TEST(dbHandle != NULL); |
|
1076 |
|
1077 RDebug::Print(_L("Create 'CompareF' collation\r\n")); |
|
1078 _LIT8(KCmpF, "CmpF8\x0"); |
|
1079 rc = sqlite3_create_collation(dbHandle, (const char*)(KCmpF().Ptr()), SQLITE_UTF8, NULL, &CmpF8); |
|
1080 if(rc) |
|
1081 { |
|
1082 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
1083 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
1084 RDebug::Print(_L("'sqlite3_create_collation()' failed, file %S, err %d, error msg: \"%S\"\r\n"), &aDbFilePath, rc, &msg); |
|
1085 TEST(0); |
|
1086 } |
|
1087 |
|
1088 RDebug::Print(_L("Create 'CompareC' collation\r\n")); |
|
1089 _LIT8(KCmpC, "CmpC8\x0"); |
|
1090 rc = sqlite3_create_collation(dbHandle, (const char*)(KCmpC().Ptr()), SQLITE_UTF8, NULL, &CmpC8); |
|
1091 if(rc) |
|
1092 { |
|
1093 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
1094 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
1095 RDebug::Print(_L("'sqlite3_create_collation()' failed, file %S, err %d, error msg: \"%S\"\r\n"), &aDbFilePath, rc, &msg); |
|
1096 TEST(0); |
|
1097 } |
|
1098 |
|
1099 RDebug::Print(_L("Create database schema\r\n")); |
|
1100 char* createSqlZ = ReadSQL2(_L("z:\\test\\contacts_schema_to_vendors.sql")); |
|
1101 ExecSql(dbHandle, createSqlZ, _L("Create schema")); |
|
1102 delete [] createSqlZ; |
|
1103 |
|
1104 RDebug::Print(_L("Add 1001 contacts\r\n")); |
|
1105 char* addSqlZ = ReadSQL2(aAddContactsFile); |
|
1106 ExecSql(dbHandle, addSqlZ, _L("Add contacts")); |
|
1107 delete [] addSqlZ; |
|
1108 |
|
1109 RDebug::Print(_L("Print the number of records\r\n")); |
|
1110 const char testSql[] = {"SELECT COUNT(*) FROM CONTACTS"}; |
|
1111 ExecSql(dbHandle, testSql, _L("SELECT COUNT(*)")); |
|
1112 |
|
1113 RDebug::Print(_L("Create index (using 'CompareF' collation): 'FirstName, Surname'\r\n")); |
|
1114 _LIT8(KCreateIndexStmt, "CREATE INDEX Idx1 ON identitytable(cm_firstname COLLATE CmpF8, cm_lastname COLLATE CmpF8)\x0"); |
|
1115 ExecSql(dbHandle, (const char*)(KCreateIndexStmt().Ptr()), _L("Create index")); |
|
1116 RDebug::Print(_L("CompareF() called %d times\r\n"), TheCmpFCallCnt); |
|
1117 |
|
1118 /* BEGIN OF - TEST CASE 1 "Select all contacts which first name begins with 'a' " */ |
|
1119 |
|
1120 RDebug::Print(_L("Prepare 'Select all contacts where the first name begins with 'A'' SQL string\r\n")); |
|
1121 _LIT8(KSearchStmt, "SELECT cm_firstname, cm_lastname FROM identitytable WHERE cm_firstname LIKE 'A%'\x0"); |
|
1122 sqlite3_stmt* stmtHandle = NULL; |
|
1123 const char* stmtTailZ = NULL; |
|
1124 TTime t1; |
|
1125 t1.UniversalTime(); |
|
1126 rc = sqlite3_prepare_v2(dbHandle, (const char*)(KSearchStmt().Ptr()), -1, &stmtHandle, &stmtTailZ); |
|
1127 TEST2(rc, SQLITE_OK); |
|
1128 TEST(stmtHandle != NULL); |
|
1129 TEST(!stmtTailZ || strlen(stmtTailZ) == 0); |
|
1130 TTime t2; |
|
1131 t2.UniversalTime(); |
|
1132 TTimeIntervalMicroSeconds diffTime = t2.MicroSecondsFrom(t1); |
|
1133 diffTime = diffTime.Int64() / 1000; |
|
1134 TInt t = (TInt)diffTime.Int64(); |
|
1135 RDebug::Print(_L("'Prepare SQL statement' time: %d ms\r\n"), t); |
|
1136 |
|
1137 RDebug::Print(_L("Step the prepared SQL statement\r\n")); |
|
1138 TInt totalCmpFCnt = 0; |
|
1139 t1.UniversalTime(); |
|
1140 TheCmpFCallCnt = 0; |
|
1141 TInt recordCnt = 0; |
|
1142 while((rc = sqlite3_step(stmtHandle)) == SQLITE_ROW) |
|
1143 { |
|
1144 //const TUint8* firstName = sqlite3_column_text(stmtHandle, 0); |
|
1145 //TPtrC8 p(firstName, strlen((const char*)firstName)); |
|
1146 //TBuf<100> p1; p1.Copy(p); |
|
1147 //const TUint8* surname = sqlite3_column_text(stmtHandle, 1); |
|
1148 //p.Set(surname, strlen((const char*)surname)); |
|
1149 //TBuf<100> p2; p2.Copy(p); |
|
1150 //RDebug::Print(_L("Found rec: %S, %S\r\n"), &p1, &p2); |
|
1151 ++recordCnt; |
|
1152 } |
|
1153 totalCmpFCnt += TheCmpFCallCnt; |
|
1154 TEST(rc == SQLITE_OK || rc == SQLITE_DONE); |
|
1155 t2.UniversalTime(); |
|
1156 diffTime = t2.MicroSecondsFrom(t1); |
|
1157 diffTime = diffTime.Int64() / 1000; |
|
1158 t = (TInt)diffTime.Int64(); |
|
1159 RDebug::Print(_L("'Stepping' time: %d ms, found records: %d\r\n"), t, recordCnt); |
|
1160 RDebug::Print(_L("Total 'search' ('CompareF' used) operations=%d\r\n"), totalCmpFCnt); |
|
1161 |
|
1162 sqlite3_finalize(stmtHandle); |
|
1163 stmtHandle = NULL; |
|
1164 |
|
1165 /* END OF - TEST CASE 1 "Select all contacts which first name begins with 'a' " */ |
|
1166 |
|
1167 /* BEGIN OF - TEST CASE 2 "Do 100 searches in 1001 contacts" */ |
|
1168 |
|
1169 RDebug::Print(_L("Prepare 'SELECT FirstName, Surname...' SQL string\r\n")); |
|
1170 _LIT8(KSearchStmt2, "SELECT cm_firstname, cm_lastname FROM identitytable WHERE cm_firstname = :Prm1 AND cm_lastname = :Prm2\x0"); |
|
1171 stmtHandle = NULL; |
|
1172 stmtTailZ = NULL; |
|
1173 t1.UniversalTime(); |
|
1174 rc = sqlite3_prepare_v2(dbHandle, (const char*)(KSearchStmt2().Ptr()), -1, &stmtHandle, &stmtTailZ); |
|
1175 TEST2(rc, SQLITE_OK); |
|
1176 TEST(stmtHandle != NULL); |
|
1177 TEST(!stmtTailZ || strlen(stmtTailZ) == 0); |
|
1178 t2.UniversalTime(); |
|
1179 diffTime = t2.MicroSecondsFrom(t1); |
|
1180 diffTime = diffTime.Int64() / 1000; |
|
1181 t = (TInt)diffTime.Int64(); |
|
1182 RDebug::Print(_L("'Prepare SQL statement' time: %d ms\r\n"), t); |
|
1183 |
|
1184 TInt idxPrm1 = sqlite3_bind_parameter_index(stmtHandle, ":Prm1"); |
|
1185 TEST(idxPrm1 > 0); |
|
1186 TInt idxPrm2 = sqlite3_bind_parameter_index(stmtHandle, ":Prm2"); |
|
1187 TEST(idxPrm2 > 0); |
|
1188 |
|
1189 RDebug::Print(_L("Do %d searches using the prepared SQL statement\r\n"), KNamesCnt); |
|
1190 totalCmpFCnt = 0; |
|
1191 t1.UniversalTime(); |
|
1192 for(TInt i=0;i<KNamesCnt;++i) |
|
1193 { |
|
1194 const TDesC8& firstName = KNames[i].iFirstName; |
|
1195 rc = sqlite3_bind_text(stmtHandle, idxPrm1, (const char*)firstName.Ptr(), firstName.Length(), SQLITE_STATIC); |
|
1196 TEST2(rc, SQLITE_OK); |
|
1197 |
|
1198 const TDesC8& surname = KNames[i].iSurname; |
|
1199 rc = sqlite3_bind_text(stmtHandle, idxPrm2, (const char*)surname.Ptr(), surname.Length(), SQLITE_STATIC); |
|
1200 TEST2(rc, SQLITE_OK); |
|
1201 |
|
1202 TheCmpFCallCnt = 0; |
|
1203 TInt recordCnt = 0; |
|
1204 while((rc = sqlite3_step(stmtHandle)) == SQLITE_ROW) |
|
1205 { |
|
1206 ++recordCnt; |
|
1207 } |
|
1208 totalCmpFCnt += TheCmpFCallCnt; |
|
1209 TEST(recordCnt == 1); |
|
1210 rc = sqlite3_reset(stmtHandle); |
|
1211 TEST2(rc, SQLITE_OK); |
|
1212 } |
|
1213 t2.UniversalTime(); |
|
1214 diffTime = t2.MicroSecondsFrom(t1); |
|
1215 diffTime = diffTime.Int64() / 1000; |
|
1216 t = (TInt)diffTime.Int64(); |
|
1217 RDebug::Print(_L("'Search' time: %d ms\r\n"), t); |
|
1218 RDebug::Print(_L("Total 'search' ('CompareF' used) operations=%d, average_per_iter=%d\r\n"), totalCmpFCnt, totalCmpFCnt/KNamesCnt); |
|
1219 |
|
1220 sqlite3_finalize(stmtHandle); |
|
1221 stmtHandle = NULL; |
|
1222 |
|
1223 /* END OF - TEST CASE 2 "Do 100 searches in 1001 contacts" */ |
|
1224 |
|
1225 t1.UniversalTime(); |
|
1226 sqlite3_finalize(stmtHandle); |
|
1227 t2.UniversalTime(); |
|
1228 diffTime = t2.MicroSecondsFrom(t1); |
|
1229 diffTime = diffTime.Int64() / 1000; |
|
1230 t = (TInt)diffTime.Int64(); |
|
1231 RDebug::Print(_L("'Finalize SQL statement' time: %d ms\r\n"), t); |
|
1232 |
|
1233 sqlite3_close(dbHandle); |
|
1234 PrintFileSize(aDbFilePath); |
|
1235 } |
|
1236 |
|
1237 static void TwoDatabasesTest() |
|
1238 { |
|
1239 (void)sqlite3SymbianLastOsError(); |
|
1240 sqlite3 *dbHandle1 = NULL; |
|
1241 TInt rc1 = sqlite3_open(KDbName1, &dbHandle1); |
|
1242 if(rc1 != SQLITE_OK) |
|
1243 { |
|
1244 rc1 = sqlite3SymbianLastOsError(); |
|
1245 } |
|
1246 |
|
1247 (void)sqlite3SymbianLastOsError(); |
|
1248 sqlite3 *dbHandle2 = NULL; |
|
1249 TInt rc2 = sqlite3_open(KDbName1, &dbHandle2); |
|
1250 if(rc2 != SQLITE_OK) |
|
1251 { |
|
1252 rc2 = sqlite3SymbianLastOsError(); |
|
1253 } |
|
1254 |
|
1255 sqlite3_close(dbHandle2); |
|
1256 |
|
1257 sqlite3_close(dbHandle1); |
|
1258 |
|
1259 (void)TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
1260 |
|
1261 TEST2(rc1, KErrNone); |
|
1262 TEST2(rc2, KErrInUse);//EFileRead | EFileWrite file open mode! |
|
1263 } |
|
1264 |
|
1265 static void QuickTest() |
|
1266 { |
|
1267 (void)TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
1268 |
|
1269 sqlite3 *dbHandle1 = NULL; |
|
1270 TInt err = sqlite3_open(KDbName1, &dbHandle1); |
|
1271 TEST2(err, SQLITE_OK); |
|
1272 |
|
1273 err = sqlite3_exec(dbHandle1, "CREATE TABLE A(Fld1 INTEGER, Fld2 TEXT);", 0, 0, 0); |
|
1274 TEST2(err, SQLITE_OK); |
|
1275 |
|
1276 sqlite3_stmt* stmtHandle = NULL; |
|
1277 _LIT(KSql1, "INSERT INTO A(Fld1, Fld2) VALUES(1, :Val)\x0"); |
|
1278 err = sqlite3_prepare16_v2(dbHandle1, KSql1().Ptr(), -1, &stmtHandle, NULL); |
|
1279 TEST2(err, SQLITE_OK); |
|
1280 |
|
1281 _LIT(KPrmData, "U012"); |
|
1282 err = sqlite3_bind_text16(stmtHandle, 1, (const void*)KPrmData().Ptr(), KPrmData().Length() * sizeof(TText), SQLITE_STATIC); |
|
1283 TEST2(err, SQLITE_OK); |
|
1284 |
|
1285 while((err = sqlite3_step(stmtHandle)) == SQLITE_ROW) |
|
1286 { |
|
1287 } |
|
1288 if(err == SQLITE_ERROR) //It may be "out of memory" problem |
|
1289 { |
|
1290 err = sqlite3_reset(stmtHandle); |
|
1291 __ASSERT_ALWAYS(err != SQLITE_OK, User::Invariant()); |
|
1292 } |
|
1293 |
|
1294 sqlite3_finalize(stmtHandle); |
|
1295 |
|
1296 _LIT(KSql2, "SELECT * FROM A WHERE Fld1 = 1\x0"); |
|
1297 err = sqlite3_prepare16_v2(dbHandle1, KSql2().Ptr(), -1, &stmtHandle, NULL); |
|
1298 TEST2(err, SQLITE_OK); |
|
1299 |
|
1300 err = sqlite3_step(stmtHandle); |
|
1301 TEST2(err, SQLITE_ROW); |
|
1302 |
|
1303 const void* data = sqlite3_column_text16(stmtHandle, 1); |
|
1304 UNUSED_VAR(data); |
|
1305 TInt charLength = sqlite3_column_bytes16(stmtHandle, 1) / sizeof(TUint16); |
|
1306 UNUSED_VAR(charLength); |
|
1307 |
|
1308 sqlite3_finalize(stmtHandle); |
|
1309 |
|
1310 sqlite3_close(dbHandle1); |
|
1311 |
|
1312 (void)TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
1313 } |
|
1314 |
|
1315 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1316 |
|
1317 static void TemdDbTest() |
|
1318 { |
|
1319 sqlite3 *dbHandle = NULL; |
|
1320 TInt rc = sqlite3_open(KDbName1, &dbHandle); |
|
1321 if(rc != SQLITE_OK) |
|
1322 { |
|
1323 const void* errMsgZ = sqlite3_errmsg16(dbHandle); |
|
1324 TPtrC msg(reinterpret_cast <const TText16*> (errMsgZ), wcslen(reinterpret_cast <const wchar_t*> (errMsgZ))); |
|
1325 RDebug::Print(_L("'sqlite3_open()' failed, err %d, error msg: \"%S\"\r\n"), rc, &msg); |
|
1326 TEST(0); |
|
1327 } |
|
1328 TEST(dbHandle != NULL); |
|
1329 |
|
1330 char *zErrMsg = 0; |
|
1331 |
|
1332 _LIT8(KSql1, "CREATE TEMP TABLE A(F1 INTEGER)\x0"); |
|
1333 rc = sqlite3_exec(dbHandle, reinterpret_cast <const char*> (KSql1().Ptr()), callback, 0, &zErrMsg); |
|
1334 if(rc != SQLITE_OK) |
|
1335 { |
|
1336 TPtrC p = ConvertToUtf16(zErrMsg); |
|
1337 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
1338 sqlite3_free(zErrMsg); |
|
1339 TEST(0); |
|
1340 } |
|
1341 |
|
1342 _LIT8(KSql2, "INSERT INTO A(F1) VALUES(2)\x0"); |
|
1343 rc = sqlite3_exec(dbHandle, reinterpret_cast <const char*> (KSql2().Ptr()), callback, 0, &zErrMsg); |
|
1344 if(rc != SQLITE_OK) |
|
1345 { |
|
1346 TPtrC p = ConvertToUtf16(zErrMsg); |
|
1347 RDebug::Print(_L("SQL error %d, msg: %S\n"), rc, &p); |
|
1348 sqlite3_free(zErrMsg); |
|
1349 TEST(0); |
|
1350 } |
|
1351 |
|
1352 sqlite3_close(dbHandle); |
|
1353 (void)TheFs.Delete(ConvertToUtf16(KDbName1)); |
|
1354 } |
|
1355 |
|
1356 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1357 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1358 ////////////////////////////////////////////////////////////////////////////////////////////////// |
|
1359 |
|
1360 static void CreateTestDir() |
|
1361 { |
|
1362 RFs fs; |
|
1363 TInt err = fs.Connect(); |
|
1364 TEST2(err, KErrNone); |
|
1365 |
|
1366 err = fs.MkDir(KTestDir); |
|
1367 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
1368 |
|
1369 fs.Close(); |
|
1370 } |
|
1371 |
|
1372 static void DoTestsL() |
|
1373 { |
|
1374 TheTest.Next(_L("Attempt to open twice the same database file in the same thread")); |
|
1375 TwoDatabasesTest(); |
|
1376 |
|
1377 TheTest.Next(_L("TEMP database test")); |
|
1378 TemdDbTest(); |
|
1379 |
|
1380 TheTest.Next(_L("Quick test")); |
|
1381 QuickTest(); |
|
1382 |
|
1383 TheTest.Next(_L("SQLite tests 1")); |
|
1384 DoTests1(); |
|
1385 |
|
1386 TheTest.Next(_L("SQLite tests 2")); |
|
1387 DoTests2(); |
|
1388 |
|
1389 TheTest.Next(_L("Accented column names")); |
|
1390 AccentedColumnNamesTestL(); |
|
1391 |
|
1392 TFileName fname; |
|
1393 User::CommandLine(fname); |
|
1394 TParse parse; |
|
1395 parse.Set(fname, &KContactsFile, 0); |
|
1396 const TDesC& dbFilePath = parse.FullName(); |
|
1397 |
|
1398 PrintConfig(dbFilePath); |
|
1399 |
|
1400 TheTest.Next(_L("String searching tests. 16-bit strings. Simple contacts")); |
|
1401 SearchDbTest16(dbFilePath); |
|
1402 |
|
1403 TheTest.Next(_L("String searching tests. 8-bit strings. Simple contacts")); |
|
1404 SearchDbTest8(dbFilePath, KSimpleContactsSqlFile, _L("Search simple contacts")); |
|
1405 } |
|
1406 |
|
1407 TInt E32Main() |
|
1408 { |
|
1409 TheTest.Title(); |
|
1410 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-LEGACY-T_SQLITE-0001 SQLite tests ")); |
|
1411 |
|
1412 TheTrapCleanup = CTrapCleanup::New (); |
|
1413 __ASSERT_ALWAYS(TheTrapCleanup != NULL, User::Invariant()); |
|
1414 |
|
1415 __UHEAP_MARK; |
|
1416 |
|
1417 CreateTestDir(); |
|
1418 |
|
1419 TheTest(TheFs.Connect() == KErrNone); |
|
1420 DeleteTestFiles(); |
|
1421 |
|
1422 CreatePrivateDirs(); |
|
1423 |
|
1424 //Init sqlite library |
|
1425 sqlite3SymbianLibInit(); |
|
1426 |
|
1427 TRAPD(err, DoTestsL()); |
|
1428 |
|
1429 sqlite3SymbianLibFinalize(); |
|
1430 |
|
1431 CloseSTDLIB(); |
|
1432 |
|
1433 DeleteTestFiles(); |
|
1434 |
|
1435 TEST2(err, KErrNone); |
|
1436 |
|
1437 TheFs.Close(); |
|
1438 |
|
1439 __UHEAP_MARKEND; |
|
1440 |
|
1441 delete TheTrapCleanup; |
|
1442 |
|
1443 |
|
1444 TheTest.End(); |
|
1445 TheTest.Close(); |
|
1446 |
|
1447 |
|
1448 return KErrNone; |
|
1449 } |