|
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 <d32dbms.h> |
|
17 #include <s32file.h> |
|
18 #include <e32test.h> |
|
19 #include <e32math.h> |
|
20 #include <s32mem.h> |
|
21 #include <hal.h> |
|
22 |
|
23 static RTest TheTest(_L("t_dbperf3")); |
|
24 static CTrapCleanup* TheTrapCleanup; |
|
25 static RFs TheFs; |
|
26 static RDbs TheDbs; |
|
27 static RDbNamedDatabase TheDatabase; |
|
28 static RDbRowSet TheRowSet, TheRowSet2; |
|
29 static RFile TheTestFile; |
|
30 static TFileName TheDatabaseFileName; |
|
31 |
|
32 #define COUNT_OF(array) (sizeof(array)/sizeof(array[0])) |
|
33 |
|
34 const TInt KTrackRecordCount = 200; |
|
35 const TInt KCategoryRecordCount = 50; |
|
36 const TInt KStatsRecordCount = 50; |
|
37 const TInt KTestBlobSize = 4096; |
|
38 |
|
39 //_LIT(KCreateTrackTable, "CREATE TABLE TRACKS (id INTEGER, marked_2_play INTEGER, category_id INTEGER, artist_last_name CHAR(15) NOT NULL,artist_first_name CHAR(15) NOT NULL, title CHAR(16) NOT NULL,download_site CHAR(30) NOT NULL,band_name CHAR(20) NOT NULL,origin CHAR(16),autostart INTEGER, init_volume INTEGER, music_file LONG VARCHAR)"); |
|
40 _LIT(KCreateTrackIndex, "CREATE INDEX IDX1 ON TRACKS(id,marked_2_play,category_id)"); |
|
41 _LIT(KCreateTrackTable, "CREATE TABLE TRACKS (id INTEGER, marked_2_play INTEGER, category_id INTEGER, artist_last_name CHAR(15) NOT NULL,artist_first_name CHAR(15) NOT NULL, title CHAR(16) NOT NULL,download_site CHAR(30) NOT NULL,band_name CHAR(20) NOT NULL,origin CHAR(16),autostart INTEGER, init_volume INTEGER)"); |
|
42 _LIT(KCreateTrackTable2, "CREATE TABLE TRACKS2 (id INTEGER, music_file LONG VARCHAR)"); |
|
43 //_LIT(KCreateTrackIndex2, "CREATE INDEX IDX4 ON TRACKS2(id)"); |
|
44 |
|
45 //_LIT(KTrackTable,"TRACKS"); |
|
46 |
|
47 _LIT(KId,"id"); |
|
48 _LIT(KLastName,"artist_last_name"); |
|
49 _LIT(KFirstName,"artist_first_name"); |
|
50 _LIT(KTitle,"title"); |
|
51 _LIT(KDownloadSite,"download_site"); |
|
52 _LIT(KBandName,"band_name"); |
|
53 _LIT(KOrigin,"origin"); |
|
54 _LIT(KAutoStart,"autostart"); |
|
55 _LIT(KInitVolume,"init_volume"); |
|
56 _LIT(KMarked2Play,"marked_2_play"); |
|
57 _LIT(KCategoryId,"category_id"); |
|
58 _LIT(KMusicFile,"music_file"); |
|
59 |
|
60 |
|
61 //category Table LITS |
|
62 _LIT(KCreateCategoryTable, "CREATE TABLE CATEGORY (category_id INTEGER,category_name CHAR(20),genre INTEGER)"); |
|
63 _LIT(KCreateCategoryIndex, "CREATE INDEX IDX2 ON CATEGORY(category_id)"); |
|
64 |
|
65 //_LIT(KCategoryTable,"CATEGORY"); |
|
66 |
|
67 //KCategoryId defined for category table |
|
68 _LIT(KCategoryName,"category_name"); |
|
69 _LIT(KGenre,"genre"); |
|
70 |
|
71 |
|
72 //STATS Table LITS |
|
73 _LIT(KCreatestatsTable, "CREATE TABLE STATS (category_id INTEGER, no_of_tracks INTEGER, no_autostart INTEGER,no_manualstart INTEGER,no_marked_2_play INTEGER, no_unmarked_2_play INTEGER, size_of_musicfiles INTEGER)"); |
|
74 _LIT(KCreatestatsIndex, "CREATE UNIQUE INDEX IDX3 ON STATS(category_id)"); |
|
75 |
|
76 //_LIT(KStatsTable,"STATS"); |
|
77 |
|
78 //KCategoryId defined for category table |
|
79 _LIT(KNoOfTracks,"no_of_tracks"); |
|
80 _LIT(KNoMarked2Play,"no_marked_2_play"); |
|
81 _LIT(KNoUnmarked2Play,"no_unmarked_2_play"); |
|
82 _LIT(KNoAutostart,"no_autostart"); |
|
83 _LIT(KNoManualStart,"no_manualstart"); |
|
84 _LIT(KSizeOfMusicFiles,"size_of_musicfiles"); |
|
85 |
|
86 ////////////////////////////////////////////////////// |
|
87 |
|
88 static TInt TheCounterFreq = -10000000; |
|
89 const TInt KMicroSecIn1Sec = 1000000; |
|
90 |
|
91 TUint32 CalcTickDiff(TUint32 aStartTicks, TUint32 aEndTicks) |
|
92 { |
|
93 TInt64 diffTicks = (TInt64)aEndTicks - (TInt64)aStartTicks; |
|
94 if(diffTicks < 0) |
|
95 { |
|
96 diffTicks = KMaxTUint32 + diffTicks + 1; |
|
97 } |
|
98 return (TUint32)diffTicks; |
|
99 } |
|
100 |
|
101 //Prints aFastCount parameter (converted to us) |
|
102 void PrintFcDiffAsUs(const TDesC& aFormatStr, TUint32 aFastCount) |
|
103 { |
|
104 double v = ((double)aFastCount * KMicroSecIn1Sec) / (double)TheCounterFreq; |
|
105 TInt v2 = (TInt)v; |
|
106 TheTest.Printf(aFormatStr, v2); |
|
107 } |
|
108 |
|
109 /////////////////////////////////////////////////////////////////////////////////////// |
|
110 |
|
111 //Delete "aFullName" file. |
|
112 static void DeleteFile(const TDesC& aFullName) |
|
113 { |
|
114 RFs fsSession; |
|
115 TInt err = fsSession.Connect(); |
|
116 if(err == KErrNone) |
|
117 { |
|
118 TEntry entry; |
|
119 if(fsSession.Entry(aFullName, entry) == KErrNone) |
|
120 { |
|
121 err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); |
|
122 if(err != KErrNone) |
|
123 { |
|
124 TheTest.Printf(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); |
|
125 } |
|
126 err = fsSession.Delete(aFullName); |
|
127 if(err != KErrNone) |
|
128 { |
|
129 TheTest.Printf(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); |
|
130 } |
|
131 } |
|
132 fsSession.Close(); |
|
133 } |
|
134 else |
|
135 { |
|
136 TheTest.Printf(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); |
|
137 } |
|
138 } |
|
139 |
|
140 /////////////////////////////////////////////////////////////////////////////////////// |
|
141 |
|
142 static void CloseAll() |
|
143 { |
|
144 TheRowSet2.Close(); |
|
145 TheRowSet.Close(); |
|
146 TheDatabase.Close(); |
|
147 TheDbs.Close(); |
|
148 TheFs.Close(); |
|
149 } |
|
150 |
|
151 /////////////////////////////////////////////////////////////////////////////////////// |
|
152 /////////////////////////////////////////////////////////////////////////////////////// |
|
153 //Tests macros and functions. |
|
154 //If (!aValue) then the test will be panicked, the test data files will be deleted. |
|
155 static void Check(TInt aValue, TInt aLine) |
|
156 { |
|
157 if(!aValue) |
|
158 { |
|
159 CloseAll(); |
|
160 DeleteFile(TheDatabaseFileName); |
|
161 TheTest(EFalse, aLine); |
|
162 } |
|
163 } |
|
164 //If (aValue != aExpected) then the test will be panicked, the test data files will be deleted. |
|
165 static void Check(TInt aValue, TInt aExpected, TInt aLine) |
|
166 { |
|
167 if(aValue != aExpected) |
|
168 { |
|
169 TheTest.Printf(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); |
|
170 CloseAll(); |
|
171 DeleteFile(TheDatabaseFileName); |
|
172 TheTest(EFalse, aLine); |
|
173 } |
|
174 } |
|
175 //Use these to test conditions. |
|
176 #define TEST(arg) ::Check((arg), __LINE__) |
|
177 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) |
|
178 |
|
179 /////////////////////////////////////////////////////////////////////////////////////// |
|
180 |
|
181 void PrintFileSize() |
|
182 { |
|
183 RDbDatabase::TSize s = TheDatabase.Size(); |
|
184 TheTest.Printf(_L("####FileSize: %d\r\n"), s.iSize); |
|
185 } |
|
186 |
|
187 /////////////////////////////////////////////////////////////////////////////////////// |
|
188 |
|
189 void FillRandomData(TDes& aData, TInt64 aSeed) |
|
190 { |
|
191 aData.Zero(); |
|
192 for (TInt i=0; i<aData.MaxLength(); ++i) |
|
193 { |
|
194 // add next character (we stick to lowercase alphabet for now) |
|
195 aData.Append(TChar(Math::FRand(aSeed)*25 + 'a')); |
|
196 } |
|
197 } |
|
198 |
|
199 void FillRandomData(TDes& aData) |
|
200 { |
|
201 // get random seed |
|
202 TTime time; |
|
203 time.UniversalTime(); |
|
204 TInt64 seed = time.Int64(); |
|
205 // do the filling |
|
206 FillRandomData(aData, seed); |
|
207 } |
|
208 |
|
209 /////////////////////////////////////////////////////////////////////////////////////// |
|
210 |
|
211 void CreateDatabase() |
|
212 { |
|
213 TInt err = TheDatabase.Replace(TheFs, TheDatabaseFileName); |
|
214 TEST2(err, KErrNone); |
|
215 TheDatabase.Close(); |
|
216 err = TheDbs.Connect(); |
|
217 TEST2(err, KErrNone); |
|
218 err = TheDatabase.Open(TheDbs, TheDatabaseFileName); |
|
219 TEST2(err, KErrNone); |
|
220 err = TheDatabase.Execute(KCreateTrackTable); |
|
221 TEST2(err, KErrNone); |
|
222 err = TheDatabase.Execute(KCreateTrackIndex); |
|
223 TEST2(err, KErrNone); |
|
224 err = TheDatabase.Execute(KCreateTrackTable2); |
|
225 TEST2(err, KErrNone); |
|
226 //err = TheDatabase.Execute(KCreateTrackIndex2); |
|
227 //TEST2(err, KErrNone); |
|
228 err = TheDatabase.Execute(KCreateCategoryTable); |
|
229 TEST2(err, KErrNone); |
|
230 err = TheDatabase.Execute(KCreateCategoryIndex); |
|
231 TEST2(err, KErrNone); |
|
232 err = TheDatabase.Execute(KCreatestatsTable); |
|
233 TEST2(err, KErrNone); |
|
234 err = TheDatabase.Execute(KCreatestatsIndex); |
|
235 TEST2(err, KErrNone); |
|
236 //err = TheDatabase.Compact(); |
|
237 //TEST2(err, KErrNone); |
|
238 } |
|
239 |
|
240 void InsertTrackTableL() |
|
241 { |
|
242 HBufC* randomDataBuf = HBufC::NewLC(KTestBlobSize); |
|
243 TPtr randomData(randomDataBuf->Des()); |
|
244 FillRandomData(randomData); |
|
245 |
|
246 RDbView view; |
|
247 TInt err = view.Prepare(TheDatabase, _L("select * from TRACKS"), view.EInsertOnly); |
|
248 TEST2(err, KErrNone); |
|
249 TheRowSet = view; |
|
250 |
|
251 CDbColSet* colSet = TheRowSet.ColSetL(); |
|
252 const TInt KIdIdx = colSet->ColNo(KId); |
|
253 const TInt KLastNameIdx = colSet->ColNo(KLastName); |
|
254 const TInt KFirstNameIdx = colSet->ColNo(KFirstName); |
|
255 const TInt KTitleIdx = colSet->ColNo(KTitle); |
|
256 const TInt KDownloadSiteIdx = colSet->ColNo(KDownloadSite); |
|
257 const TInt KBandNameIdx = colSet->ColNo(KBandName); |
|
258 const TInt KOriginIdx = colSet->ColNo(KOrigin); |
|
259 const TInt KAutoStartIdx = colSet->ColNo(KAutoStart); |
|
260 const TInt KInitVolumeIdx = colSet->ColNo(KInitVolume); |
|
261 const TInt KMarkedToPlayIdx = colSet->ColNo(KMarked2Play); |
|
262 const TInt KCategoryIdIdx = colSet->ColNo(KCategoryId); |
|
263 //const TInt KMusicFileIdx = colSet->ColNo(KMusicFile); |
|
264 delete colSet; |
|
265 colSet = NULL; |
|
266 |
|
267 err = TheDatabase.Begin(); |
|
268 TEST2(err, KErrNone); |
|
269 |
|
270 for (TInt ii=1;ii<=KTrackRecordCount;++ii) |
|
271 { |
|
272 TheRowSet.InsertL(); |
|
273 TheRowSet.SetColL(KIdIdx, ii); |
|
274 TheRowSet.SetColL(KLastNameIdx, _L("Dummy")); |
|
275 TheRowSet.SetColL(KFirstNameIdx,_L("Dummy")); |
|
276 TheRowSet.SetColL(KTitleIdx,_L("Dummy")); |
|
277 TheRowSet.SetColL(KDownloadSiteIdx,_L("Dummy")); |
|
278 TheRowSet.SetColL(KBandNameIdx,_L("Dummy")); |
|
279 TheRowSet.SetColL(KOriginIdx,_L("Dummy")); |
|
280 TheRowSet.SetColL(KAutoStartIdx,(ii%2)); |
|
281 TheRowSet.SetColL(KInitVolumeIdx,(ii%2)); |
|
282 TheRowSet.SetColL(KMarkedToPlayIdx,(ii%2)); |
|
283 TheRowSet.SetColL(KCategoryIdIdx,(ii%KCategoryRecordCount)); |
|
284 |
|
285 //RDbColWriteStream musicfile; |
|
286 //musicfile.OpenLC(TheRowSet, KMusicFileIdx); |
|
287 //musicfile.WriteL(randomData,KTestBlobSize); |
|
288 //musicfile.CommitL(); |
|
289 //CleanupStack::PopAndDestroy(&musicfile); |
|
290 |
|
291 TheRowSet.PutL(); |
|
292 } |
|
293 |
|
294 err = TheDatabase.Commit(); |
|
295 TEST2(err, KErrNone); |
|
296 |
|
297 //err = TheDatabase.Compact(); |
|
298 //TEST2(err, KErrNone); |
|
299 |
|
300 TheRowSet.Close(); |
|
301 |
|
302 //////////////////////////////////////////////////////////////////////////////////////////////// |
|
303 |
|
304 err = view.Prepare(TheDatabase, _L("select * from TRACKS2"), view.EInsertOnly); |
|
305 TEST2(err, KErrNone); |
|
306 TheRowSet = view; |
|
307 |
|
308 colSet = TheRowSet.ColSetL(); |
|
309 const TInt KIdIdx2 = colSet->ColNo(KId); |
|
310 const TInt KMusicFileIdx2 = colSet->ColNo(KMusicFile); |
|
311 delete colSet; |
|
312 |
|
313 err = TheDatabase.Begin(); |
|
314 TEST2(err, KErrNone); |
|
315 |
|
316 for (TInt ii=1;ii<=KTrackRecordCount;++ii) |
|
317 { |
|
318 TheRowSet.InsertL(); |
|
319 TheRowSet.SetColL(KIdIdx2, ii); |
|
320 |
|
321 RDbColWriteStream musicfile; |
|
322 musicfile.OpenLC(TheRowSet, KMusicFileIdx2); |
|
323 musicfile.WriteL(randomData,KTestBlobSize); |
|
324 musicfile.CommitL(); |
|
325 CleanupStack::PopAndDestroy(&musicfile); |
|
326 |
|
327 TheRowSet.PutL(); |
|
328 } |
|
329 |
|
330 err = TheDatabase.Commit(); |
|
331 TEST2(err, KErrNone); |
|
332 |
|
333 //err = TheDatabase.Compact(); |
|
334 //TEST2(err, KErrNone); |
|
335 |
|
336 TheRowSet.Close(); |
|
337 |
|
338 CleanupStack::PopAndDestroy(randomDataBuf); |
|
339 } |
|
340 |
|
341 void InsertCategoryTableL() |
|
342 { |
|
343 RDbView view; |
|
344 TInt err = view.Prepare(TheDatabase, _L("select * from CATEGORY"), view.EInsertOnly); |
|
345 TEST2(err, KErrNone); |
|
346 TheRowSet = view; |
|
347 |
|
348 CDbColSet* colSet = TheRowSet.ColSetL(); |
|
349 const TInt KCategoryIdIdx = colSet->ColNo(KCategoryId); |
|
350 const TInt KCategoryNameIdx = colSet->ColNo(KCategoryName); |
|
351 const TInt KGenreIdx = colSet->ColNo(KGenre); |
|
352 delete colSet; |
|
353 |
|
354 err = TheDatabase.Begin(); |
|
355 TEST2(err, KErrNone); |
|
356 |
|
357 for (TInt ii=1;ii<=KCategoryRecordCount;++ii) |
|
358 { |
|
359 TheRowSet.InsertL(); |
|
360 TheRowSet.SetColL(KCategoryIdIdx, ii); |
|
361 TheRowSet.SetColL(KCategoryNameIdx, _L("History")); |
|
362 TheRowSet.SetColL(KGenreIdx,(ii*500)); |
|
363 TheRowSet.PutL(); |
|
364 } |
|
365 |
|
366 err = TheDatabase.Commit(); |
|
367 TEST2(err, KErrNone); |
|
368 |
|
369 //err = TheDatabase.Compact(); |
|
370 //TEST2(err, KErrNone); |
|
371 |
|
372 TheRowSet.Close(); |
|
373 } |
|
374 |
|
375 void InsertStatsTableL() |
|
376 { |
|
377 RDbView view; |
|
378 TInt err = view.Prepare(TheDatabase, _L("select * from STATS"), view.EInsertOnly); |
|
379 TEST2(err, KErrNone); |
|
380 TheRowSet = view; |
|
381 |
|
382 CDbColSet* colSet = TheRowSet.ColSetL(); |
|
383 const TInt KCategoryIdIdx = colSet->ColNo(KCategoryId); |
|
384 const TInt KTrackCntIdx = colSet->ColNo(KNoOfTracks); |
|
385 const TInt KMarkedToPlayCntIdx = colSet->ColNo(KNoMarked2Play); |
|
386 const TInt KUnmarkedToPlayCntIdx = colSet->ColNo(KNoUnmarked2Play); |
|
387 const TInt KAutoStartCntIdx = colSet->ColNo(KNoAutostart); |
|
388 const TInt KManualStartCntIdx = colSet->ColNo(KNoManualStart); |
|
389 const TInt KSizeMusicFilesIdx = colSet->ColNo(KSizeOfMusicFiles); |
|
390 delete colSet; |
|
391 |
|
392 TInt default_Stat = 0; |
|
393 |
|
394 err = TheDatabase.Begin(); |
|
395 TEST2(err, KErrNone); |
|
396 |
|
397 for (TInt ii=0;ii<KStatsRecordCount;++ii) |
|
398 { |
|
399 TheRowSet.InsertL(); |
|
400 TheRowSet.SetColL(KCategoryIdIdx, ii); |
|
401 TheRowSet.SetColL(KTrackCntIdx,default_Stat); |
|
402 TheRowSet.SetColL(KMarkedToPlayCntIdx,default_Stat); |
|
403 TheRowSet.SetColL(KUnmarkedToPlayCntIdx,default_Stat); |
|
404 TheRowSet.SetColL(KAutoStartCntIdx,default_Stat); |
|
405 TheRowSet.SetColL(KManualStartCntIdx,default_Stat); |
|
406 TheRowSet.SetColL(KSizeMusicFilesIdx,default_Stat); |
|
407 TheRowSet.PutL(); |
|
408 } |
|
409 |
|
410 err = TheDatabase.Commit(); |
|
411 TEST2(err, KErrNone); |
|
412 |
|
413 //err = TheDatabase.Compact(); |
|
414 //TEST2(err, KErrNone); |
|
415 |
|
416 TheRowSet.Close(); |
|
417 } |
|
418 |
|
419 void FillDatabaseL() |
|
420 { |
|
421 InsertTrackTableL(); |
|
422 InsertCategoryTableL(); |
|
423 InsertStatsTableL(); |
|
424 } |
|
425 |
|
426 void DestroyDatabase() |
|
427 { |
|
428 TheRowSet.Close(); |
|
429 TheDatabase.Close(); |
|
430 TheDbs.Close(); |
|
431 TInt err = TheFs.Delete(TheDatabaseFileName); |
|
432 TEST2(err, KErrNone); |
|
433 } |
|
434 |
|
435 /////////////////////////////////////////////////////////////////////////////////////// |
|
436 |
|
437 void GetFastCounterFrequency() |
|
438 { |
|
439 TEST2(HAL::Get(HAL::EFastCounterFrequency, TheCounterFreq), KErrNone); |
|
440 TheTest.Printf(_L("Counter frequency=%d\r\n"), TheCounterFreq); |
|
441 } |
|
442 |
|
443 /////////////////////////////////////////////////////////////////////////////////////// |
|
444 |
|
445 void SelectTracksL(TInt aCount, RArray<TInt>& aTracks) |
|
446 { |
|
447 TUint32 fc = User::FastCounter(); |
|
448 RDbView view; |
|
449 TUint32 fc2 = User::FastCounter(); |
|
450 TInt err = view.Prepare(TheDatabase, _L("select id from TRACKS"), view.EReadOnly); |
|
451 TEST2(err, KErrNone); |
|
452 PrintFcDiffAsUs(_L("###\"Prepare()\",time=%d us\r\n"), CalcTickDiff(fc2, User::FastCounter())); |
|
453 fc2 = User::FastCounter(); |
|
454 err = view.EvaluateAll(); |
|
455 TEST2(err, KErrNone); |
|
456 PrintFcDiffAsUs(_L("###\"EvaluateAll()\",time=%d us\r\n"), CalcTickDiff(fc2, User::FastCounter())); |
|
457 TheRowSet = view; |
|
458 |
|
459 TUint32 diff1 = 0, diff2 = 0; |
|
460 TInt count = 0; |
|
461 while(count < aCount) |
|
462 { |
|
463 fc2 = User::FastCounter(); |
|
464 if(!TheRowSet.NextL()) |
|
465 { |
|
466 break; |
|
467 } |
|
468 diff1 += CalcTickDiff(fc2, User::FastCounter()); |
|
469 fc2 = User::FastCounter(); |
|
470 TheRowSet.GetL(); |
|
471 diff2 += CalcTickDiff(fc2, User::FastCounter()); |
|
472 aTracks.Append(TheRowSet.ColInt(1)); |
|
473 ++count; |
|
474 } |
|
475 TEST2(count, aCount); |
|
476 PrintFcDiffAsUs(_L("###\"Total NextL()\",time=%d us\r\n"), diff1); |
|
477 PrintFcDiffAsUs(_L("###\"Total GetL()\",time=%d us\r\n"), diff2); |
|
478 |
|
479 fc2 = User::FastCounter(); |
|
480 TheRowSet.Close(); |
|
481 PrintFcDiffAsUs(_L("###\"Close()\",time=%d us\r\n"), CalcTickDiff(fc2, User::FastCounter())); |
|
482 PrintFcDiffAsUs(_L("###\"SELECT FROM TRACKS\",time=%d us\r\n"), CalcTickDiff(fc, User::FastCounter())); |
|
483 } |
|
484 |
|
485 /** |
|
486 @SYMTestCaseID PDS-DBMS-UT-4009 |
|
487 @SYMTestCaseDesc DBMS performance tests. |
|
488 @SYMTestPriority High |
|
489 @SYMTestActions The test opens the test database and: |
|
490 - selects the ids of the tracks to be deleted and collects them into an array; |
|
491 - deletes the recods with matching track ids from TRACK table; |
|
492 - deletes the recods with matching track ids from TRACK2 table; |
|
493 The execution times are printed out. |
|
494 @SYMTestExpectedResults Test must not fail |
|
495 @SYMREQ REQ7141 |
|
496 */ |
|
497 void DeleteTracksL() |
|
498 { |
|
499 TheTest.Printf(_L("Record count: %d\r\n"), KTrackRecordCount); |
|
500 |
|
501 RArray<TInt> tracks; |
|
502 tracks.ReserveL(KTrackRecordCount); |
|
503 CleanupClosePushL(tracks); |
|
504 SelectTracksL(KTrackRecordCount, tracks); |
|
505 // |
|
506 _LIT(KDeleteSql, "DELETE FROM tracks WHERE id>=%d AND id<=%d"); |
|
507 |
|
508 TBuf<100> sql; |
|
509 sql.Format(KDeleteSql, tracks[0], tracks[tracks.Count() - 1]); |
|
510 |
|
511 TUint32 fc2 = User::FastCounter(); |
|
512 |
|
513 TInt err = TheDatabase.Begin(); |
|
514 TEST2(err, KErrNone); |
|
515 |
|
516 TUint32 fc = User::FastCounter(); |
|
517 TInt rc = TheDatabase.Execute(sql); |
|
518 PrintFcDiffAsUs(_L("###\"DELETE FROM TRACKS\",time=%d us\r\n"), CalcTickDiff(fc, User::FastCounter())); |
|
519 TEST2(rc, KTrackRecordCount); |
|
520 TheTest.Printf(_L("Deleted record count: %d\r\n"), rc); |
|
521 |
|
522 sql.Replace(12, 6, _L("TRACKS2")); |
|
523 fc = User::FastCounter(); |
|
524 rc = TheDatabase.Execute(sql); |
|
525 PrintFcDiffAsUs(_L("###\"DELETE FROM TRACKS2\",time=%d us\r\n"), CalcTickDiff(fc, User::FastCounter())); |
|
526 TEST2(rc, KTrackRecordCount); |
|
527 TheTest.Printf(_L("Deleted record count: %d\r\n"), rc); |
|
528 |
|
529 err = TheDatabase.Commit(); |
|
530 TEST2(err, KErrNone); |
|
531 |
|
532 PrintFcDiffAsUs(_L("###Total \"DELETE FROM TRACKS\",time=%d us\r\n"), CalcTickDiff(fc2, User::FastCounter())); |
|
533 |
|
534 CleanupStack::PopAndDestroy(&tracks); |
|
535 } |
|
536 |
|
537 /////////////////////////////////////////////////////////////////////////////////////// |
|
538 |
|
539 //This test checks how RDbDatabase::Commit() works if there are some active RDbRowSet objects - |
|
540 //read-only and updatable. The expectation is that the Commit() call won't fail, the RDbRowSet objects |
|
541 //retain their pre-commit positions. |
|
542 void CommitTestL() |
|
543 { |
|
544 //Create 2 test tables, insert some records in the first table |
|
545 TheDatabase.Close(); |
|
546 TInt err = TheDatabase.Replace(TheFs, TheDatabaseFileName); |
|
547 TEST2(err, KErrNone); |
|
548 err = TheDatabase.Execute(_L("CREATE TABLE AA1(Id INTEGER)")); |
|
549 TEST2(err, KErrNone); |
|
550 err = TheDatabase.Execute(_L("CREATE TABLE AA2(Id INTEGER)")); |
|
551 TEST2(err, KErrNone); |
|
552 err = TheDatabase.Execute(_L("INSERT INTO AA1(Id) VALUES(1)")); |
|
553 TEST2(err, 1); |
|
554 err = TheDatabase.Execute(_L("INSERT INTO AA1(Id) VALUES(2)")); |
|
555 TEST2(err, 1); |
|
556 err = TheDatabase.Execute(_L("INSERT INTO AA1(Id) VALUES(3)")); |
|
557 TEST2(err, 1); |
|
558 //Begin transaction |
|
559 err = TheDatabase.Begin(); |
|
560 TEST2(err, KErrNone); |
|
561 //Prepare read-only view and call FirstL() (TheRowSet object) |
|
562 RDbView view; |
|
563 err = view.Prepare(TheDatabase, _L("select * from AA1"), RDbRowSet::EReadOnly); |
|
564 TEST2(err, KErrNone); |
|
565 TheRowSet = view; |
|
566 err = view.EvaluateAll(); //DBMS can use FirstL() without the EvaluateAll() call in this case |
|
567 TEST2(err, KErrNone); |
|
568 TBool rc = TheRowSet.FirstL(); |
|
569 TEST(rc); |
|
570 //Prepare updatable view and call NextL() (TheRowSet2 object) |
|
571 err = view.Prepare(TheDatabase, _L("select * from AA1"), RDbRowSet::EUpdatable); |
|
572 TEST2(err, KErrNone); |
|
573 TheRowSet2 = view; |
|
574 err = view.EvaluateAll(); //DBMS can use NextL() without the EvaluateAll() call in this case |
|
575 TEST2(err, KErrNone); |
|
576 rc = TheRowSet2.FirstL(); |
|
577 TEST(rc); |
|
578 rc = TheRowSet2.NextL(); |
|
579 TEST(rc); |
|
580 //Execute one INSERT statement |
|
581 err = TheDatabase.Execute(_L("INSERT INTO AA2(Id) VALUES(1)")); |
|
582 TEST2(err, 1); |
|
583 //Commit transaction |
|
584 err = TheDatabase.Commit(); |
|
585 TEST2(err, KErrNone); |
|
586 //Check the retrieved by TheRowSet record |
|
587 TheRowSet.GetL(); |
|
588 TEST2(TheRowSet.ColInt(1), 1); |
|
589 //Check the retrieved by TheRowSet2 record |
|
590 TheRowSet2.GetL(); |
|
591 TEST2(TheRowSet2.ColInt(1), 2); |
|
592 //Cleanup |
|
593 TheRowSet2.Close(); |
|
594 TheRowSet.Close(); |
|
595 TheDatabase.Close(); |
|
596 } |
|
597 |
|
598 /////////////////////////////////////////////////////////////////////////////////////// |
|
599 |
|
600 void DoTestL() |
|
601 { |
|
602 TheTest.Start(_L("Get fast counter frequency")); |
|
603 GetFastCounterFrequency(); |
|
604 |
|
605 TheTest.Next(_L("Create&Fill test database")); |
|
606 CreateDatabase(); |
|
607 FillDatabaseL(); |
|
608 |
|
609 TheTest.Next(_L(" @SYMTestCaseID:PDS-DBMS-UT-4009 Delete tracks")); |
|
610 DeleteTracksL(); |
|
611 |
|
612 TheTest.Next(_L("Commit() test (not a performance test)")); |
|
613 CommitTestL(); |
|
614 } |
|
615 |
|
616 /////////////////////////////////////////////////////////////////////////////////////// |
|
617 |
|
618 //Usage: "t_dbperf3 [<drive letter>:]" |
|
619 TInt E32Main() |
|
620 { |
|
621 TheTest.Title(); |
|
622 |
|
623 TheTrapCleanup = CTrapCleanup::New(); |
|
624 TEST(TheTrapCleanup != NULL); |
|
625 |
|
626 //Construct test database file name |
|
627 _LIT(KTestDatabase, "c:\\dbms-tst\\t_dbperf3.db"); |
|
628 TFileName fname; |
|
629 User::CommandLine(fname); |
|
630 TParse parse; |
|
631 parse.Set(fname, &KTestDatabase, 0); |
|
632 const TDesC& dbFilePath = parse.FullName(); |
|
633 TheDatabaseFileName.Copy(dbFilePath); |
|
634 TheTest.Printf(_L("Test database: %S\r\n"), &TheDatabaseFileName); |
|
635 |
|
636 __UHEAP_MARK; |
|
637 |
|
638 TInt err = TheFs.Connect(); |
|
639 TEST2(err, KErrNone); |
|
640 err = TheFs.MkDir(TheDatabaseFileName); |
|
641 TheTest.Printf(_L("MkDir(): err=%d\r\n"), err); |
|
642 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
643 |
|
644 DeleteFile(TheDatabaseFileName); |
|
645 |
|
646 TRAP(err, DoTestL()); |
|
647 TEST2(err, KErrNone); |
|
648 |
|
649 CloseAll(); |
|
650 DeleteFile(TheDatabaseFileName); |
|
651 |
|
652 __UHEAP_MARKEND; |
|
653 |
|
654 TheTest.End(); |
|
655 TheTest.Close(); |
|
656 |
|
657 delete TheTrapCleanup; |
|
658 return KErrNone; |
|
659 } |