|
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 /** |
|
17 @SYMPREQ PREQ1187 |
|
18 @SYMComponent app-engines_cntmodel |
|
19 @SYMAuthor Simon Mellor, JamesCl |
|
20 @SYMTestStatus Implemented |
|
21 @SYMTestType CT |
|
22 |
|
23 @SYMTestCaseDesc Tests the performance of Reading and Updating a single contact and of |
|
24 Matching Contacts by Phone Number on a corporate profile database of |
|
25 1000 contacts. |
|
26 |
|
27 @SYMTestActions Measures the time taken to: |
|
28 -- Attempt to match a phone number using CContactDatabase::MatchPhoneNumberL() |
|
29 -- Create a contact using CContactDatabase::AddNewContactL() |
|
30 -- Read a contact using CContactDatabase::OpenContactLX() |
|
31 -- Update a contact using CContactDatabase::CommitContactL() |
|
32 -- Delete a contact using CContactDatabase::DeleteContactL() |
|
33 |
|
34 @SYMTestExpectedResults Test cases will run without leaving and will output timing information. |
|
35 |
|
36 */ |
|
37 |
|
38 #include "T_PerfCrudOperations.h" |
|
39 #include "../T_UTILS.H" |
|
40 #include <cntitem.h> |
|
41 |
|
42 // Constants |
|
43 _LIT(KDbPathName,"C:Contacts.cdb"); |
|
44 const TPtrC KDbPath( (KDbPathName) ); |
|
45 |
|
46 |
|
47 CCrudOperations::CCrudOperations() |
|
48 { |
|
49 } |
|
50 |
|
51 CCrudOperations::~CCrudOperations() |
|
52 { |
|
53 iDb->CloseTables(); |
|
54 delete iDb; |
|
55 } |
|
56 |
|
57 CCrudOperations* CCrudOperations::NewLC(RTest& aTest) |
|
58 { |
|
59 CCrudOperations* self = new(ELeave) CCrudOperations(); |
|
60 CleanupStack::PushL(self); |
|
61 self->ConstructL(aTest); |
|
62 return(self); |
|
63 } |
|
64 |
|
65 void CCrudOperations::ConstructL(RTest& aTest) |
|
66 { |
|
67 iTest = &aTest; |
|
68 iDb = CContactDatabase::OpenL(KDbPath); |
|
69 CCntTest::ProfileReset(0, 59); |
|
70 } |
|
71 |
|
72 /** |
|
73 Main test routine. |
|
74 */ |
|
75 void CCrudOperations::DoTestsL(TInt aNumMsToGet20ItemsFromView) |
|
76 { |
|
77 iNumMsToGet20ItemsFromView= aNumMsToGet20ItemsFromView; |
|
78 |
|
79 // As, at this point, we haven't used the database before, this is the |
|
80 // equivalent of startup. We fetch a contact as a bare minimum operation |
|
81 // on the database to ensure that we fetch and cache the system template. |
|
82 // Then, we just get rid of the contact item as we don't actually want it. |
|
83 const TInt KContactIdOne(1); |
|
84 CContactItem* tmpItem = iDb->ReadContactLC(KContactIdOne); |
|
85 CleanupStack::PopAndDestroy(tmpItem); |
|
86 tmpItem = NULL; |
|
87 |
|
88 MatchContactsByPhoneNumL(); |
|
89 MatchContactsByEmailAndSipL(); |
|
90 DoCrudTestsL(); |
|
91 } |
|
92 |
|
93 /** |
|
94 Try to match the phone number given with existing numbers in the database. |
|
95 */ |
|
96 void CCrudOperations::MatchContactsByPhoneNumL() |
|
97 { |
|
98 _LIT(KPass, "Pass"); |
|
99 _LIT(KFail, "Fail"); |
|
100 _LIT(KMatchOutputFormat1, "Number of phone numbers matched: %d -- %s\n"); |
|
101 _LIT(KMatchOutputFormat2, "Phone number lookup took: %d s %03d\n"); |
|
102 _LIT(KMatchOutputFormat3, "The contact's first name: %S\n"); |
|
103 |
|
104 _LIT(KPhoneNumberToFind, "241867306233253164487125"); // this number belongs to the 1000th |
|
105 // contact item in the database, which |
|
106 // has a photo. |
|
107 |
|
108 const TInt KMatchLengthFromRight(7); // match on the number without the dialling code prefix |
|
109 // to avoid differences like +447876... and 07876... |
|
110 _LIT(KPhoneNumberTestTitle, "\nBeginning Phone Number Match testing...\n"); |
|
111 |
|
112 |
|
113 iTest->Printf(KPhoneNumberTestTitle); |
|
114 TCntPerfTimer timer; |
|
115 timer.StartTimer(); |
|
116 |
|
117 // Search the database... |
|
118 CContactIdArray* idArray = iDb->MatchPhoneNumberL(KPhoneNumberToFind, KMatchLengthFromRight); |
|
119 CleanupStack::PushL(idArray); |
|
120 TInt numMatches = idArray->Count(); |
|
121 iTest->Printf(KMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr()); |
|
122 |
|
123 if (numMatches) |
|
124 { |
|
125 //fetch first contact item in array |
|
126 CContactItem* item = iDb->ReadContactLC((*idArray)[0]); |
|
127 timer.StopTimer(); |
|
128 CContactItemFieldSet& fieldSet = item->CardFields(); |
|
129 TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName); |
|
130 if (firstNameFieldId == KErrNotFound) |
|
131 { |
|
132 User::Leave(KErrNotFound); |
|
133 } |
|
134 CContactItemField& firstNameField = fieldSet[firstNameFieldId]; |
|
135 CContactTextField* firstNameText = firstNameField.TextStorage(); |
|
136 TPtrC firstName(firstNameText->Text()); |
|
137 iTest->Printf(KMatchOutputFormat3, &firstName); |
|
138 |
|
139 CleanupStack::PopAndDestroy(item); |
|
140 } |
|
141 else |
|
142 { |
|
143 timer.StopTimer(); |
|
144 } |
|
145 |
|
146 CleanupStack::PopAndDestroy(idArray); |
|
147 |
|
148 TInt result = timer.Result(); |
|
149 TBuf<64> formattable; |
|
150 formattable.Format(KMatchOutputFormat2, result / 1000000, (result / 1000) % 1000); |
|
151 iTest->Printf(formattable); |
|
152 } |
|
153 |
|
154 /** |
|
155 Try to match the phone number given with existing numbers in the database. |
|
156 */ |
|
157 void CCrudOperations::MatchContactsByEmailAndSipL() |
|
158 { |
|
159 _LIT(KPass, "Pass"); |
|
160 _LIT(KFail, "Fail"); |
|
161 _LIT(KEmailMatchOutputFormat1,"Number of email addresses matched: %d -- %s\n"); |
|
162 _LIT(KEmailMatchOutputFormat2,"Email address lookup took: %d s %03d\n"); |
|
163 _LIT(KMatchOutputFormat3, "The contact's first name: %S\n"); |
|
164 |
|
165 // Test Email address matching |
|
166 |
|
167 // this address belongs to the 1000th contact item in the database, which has a photo. |
|
168 _LIT(KEmailAddressToFind, "fred.bloggs@symbian.com"); |
|
169 _LIT(KEmailTestTitle, "\nBeginning Email Address Match testing...\n"); |
|
170 |
|
171 iTest->Printf(KEmailTestTitle); |
|
172 TCntPerfTimer timer; |
|
173 timer.StartTimer(); |
|
174 |
|
175 // Search the database... |
|
176 CContactItemFieldDef* fieldsToSearch = new (ELeave) CContactItemFieldDef(); |
|
177 CleanupStack::PushL(fieldsToSearch); |
|
178 fieldsToSearch->AppendL(KUidContactFieldEMail); |
|
179 CContactIdArray* idArray = iDb->FindLC(KEmailAddressToFind, fieldsToSearch); |
|
180 TInt numMatches = idArray->Count(); |
|
181 iTest->Printf(KEmailMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr()); |
|
182 |
|
183 if (numMatches) |
|
184 { |
|
185 //fetch first contact item in array |
|
186 CContactItem* item = iDb->ReadContactLC((*idArray)[0]); |
|
187 CContactItemFieldSet& fieldSet = item->CardFields(); |
|
188 TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName); |
|
189 if (firstNameFieldId == KErrNotFound) |
|
190 { |
|
191 User::Leave(KErrNotFound); |
|
192 } |
|
193 CContactItemField& firstNameField = fieldSet[firstNameFieldId]; |
|
194 CContactTextField* firstNameText = firstNameField.TextStorage(); |
|
195 TPtrC firstName(firstNameText->Text()); |
|
196 iTest->Printf(KMatchOutputFormat3, &firstName); |
|
197 CleanupStack::PopAndDestroy(item); |
|
198 } |
|
199 |
|
200 timer.StopTimer(); |
|
201 CleanupStack::PopAndDestroy(2, fieldsToSearch); // and idArray |
|
202 |
|
203 |
|
204 TInt result = timer.Result(); |
|
205 TBuf<64> formattable; |
|
206 formattable.Format(KEmailMatchOutputFormat2, result / 1000000, (result / 1000) % 1000); |
|
207 iTest->Printf(formattable); |
|
208 |
|
209 // reset variables |
|
210 fieldsToSearch = NULL; |
|
211 idArray = NULL; |
|
212 numMatches = 0; |
|
213 timer.ResetTimer(); |
|
214 result = 0; |
|
215 formattable.Zero(); |
|
216 |
|
217 |
|
218 // Test SIP address matching |
|
219 |
|
220 // this address belongs to the 1000th contact item in the database, which has a photo. |
|
221 _LIT(KSipAddressToFind, "sip:fred.bloggs@symbian.com"); |
|
222 _LIT(KSipTestTitle, "\nBeginning SIP Address Match testing...\n"); |
|
223 _LIT(KSipMatchOutputFormat1,"Number of SIP addresses matched: %d -- %s\n"); |
|
224 _LIT(KSipMatchOutputFormat2,"SIP address lookup took: %d s %03d\n"); |
|
225 |
|
226 iTest->Printf(KSipTestTitle); |
|
227 timer.StartTimer(); |
|
228 |
|
229 // Search the database... |
|
230 fieldsToSearch = new (ELeave) CContactItemFieldDef(); |
|
231 CleanupStack::PushL(fieldsToSearch); |
|
232 fieldsToSearch->AppendL(KUidContactFieldSIPID); |
|
233 idArray = iDb->FindLC(KSipAddressToFind, fieldsToSearch); |
|
234 numMatches = idArray->Count(); |
|
235 iTest->Printf(KSipMatchOutputFormat1, numMatches, numMatches ? KPass().Ptr() : KFail().Ptr()); |
|
236 |
|
237 if (numMatches) |
|
238 { |
|
239 //fetch first contact item in array |
|
240 CContactItem* item = iDb->ReadContactLC((*idArray)[0]); |
|
241 CContactItemFieldSet& fieldSet = item->CardFields(); |
|
242 TInt firstNameFieldId = fieldSet.Find(KUidContactFieldGivenName); |
|
243 if (firstNameFieldId == KErrNotFound) |
|
244 { |
|
245 User::Leave(KErrNotFound); |
|
246 } |
|
247 CContactItemField& firstNameField = fieldSet[firstNameFieldId]; |
|
248 CContactTextField* firstNameText = firstNameField.TextStorage(); |
|
249 TPtrC firstName(firstNameText->Text()); |
|
250 iTest->Printf(KMatchOutputFormat3, &firstName); |
|
251 CleanupStack::PopAndDestroy(item); |
|
252 } |
|
253 |
|
254 timer.StopTimer(); |
|
255 CleanupStack::PopAndDestroy(2, fieldsToSearch); // and idArray |
|
256 |
|
257 result = timer.Result(); |
|
258 formattable.Format(KSipMatchOutputFormat2, result / 1000000, (result / 1000) % 1000); |
|
259 iTest->Printf(formattable); |
|
260 } |
|
261 |
|
262 |
|
263 /** |
|
264 Perform CRUD operations with 1 item in the database. |
|
265 */ |
|
266 void CCrudOperations::DoCrudTestsL() |
|
267 { |
|
268 // chosen because they have a photo field |
|
269 const TContactItemId K901stContactItemId(901); |
|
270 const TContactItemId K973rdContactItemId(973); |
|
271 const TContactItemId K926thContactItemId(926); |
|
272 |
|
273 _LIT(KCRUDTestTitle, "\nBeginning CRUD Operations on 1 Contact (with photo) testing ...\n"); |
|
274 _LIT(KCRUDTestNote, "[Figures for each write operation include time to fetch first 20 items in view.]\n"); |
|
275 iTest->Printf(KCRUDTestTitle); |
|
276 iTest->Printf(KCRUDTestNote); |
|
277 |
|
278 TCntPerfTimer timer; |
|
279 |
|
280 // fetch a contact item to seed a new one |
|
281 CContactItem* temp = iDb->OpenContactL(K901stContactItemId); |
|
282 CleanupStack::PushL(temp); |
|
283 CContactItem* item = CContactCard::NewL(temp); |
|
284 CleanupStack::PopAndDestroy(temp); |
|
285 CleanupStack::PushL(item); |
|
286 |
|
287 // Create (add) a contact with a photo |
|
288 timer.StartTimer(); |
|
289 iDb->AddNewContactL(*item); |
|
290 timer.StopTimer(); |
|
291 TInt createResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view. |
|
292 timer.ResetTimer(); |
|
293 CleanupStack::PopAndDestroy(item); |
|
294 item = NULL; |
|
295 |
|
296 // Read a contact with a photo |
|
297 timer.StartTimer(); |
|
298 item = iDb->OpenContactLX(K973rdContactItemId); // lock object put on the CleanupStack |
|
299 CleanupStack::PushL(item); |
|
300 timer.StopTimer(); |
|
301 TInt readResult = timer.Result(); |
|
302 timer.ResetTimer(); |
|
303 |
|
304 // Update the contact in the database |
|
305 timer.StartTimer(); |
|
306 iDb->CommitContactL(*item); |
|
307 timer.StopTimer(); |
|
308 TInt updateResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view. |
|
309 timer.ResetTimer(); |
|
310 CleanupStack::PopAndDestroy(item); |
|
311 item = NULL; |
|
312 CleanupStack::PopAndDestroy(); // lock object |
|
313 |
|
314 // Delete a contact with a photo |
|
315 timer.StartTimer(); |
|
316 iDb->DeleteContactL(K926thContactItemId); |
|
317 timer.StopTimer(); |
|
318 TInt deleteResult = timer.Result() + iNumMsToGet20ItemsFromView; // add the time to fetch 20 items from view. |
|
319 timer.ResetTimer(); |
|
320 |
|
321 // output timing result |
|
322 _LIT(KCreateOutputFormat,"Creating (adding) 1 contact took: %d s %03d\n"); |
|
323 iTest->Printf(KCreateOutputFormat, createResult / 1000000, (createResult / 1000) % 1000); |
|
324 |
|
325 _LIT(KReadOutputFormat,"Reading 1 contact took: %d s %03d\n"); |
|
326 iTest->Printf(KReadOutputFormat, readResult / 1000000, (readResult / 1000) % 1000); |
|
327 |
|
328 _LIT(KUpdateOutputFormat,"Updating 1 contact took: %d s %03d\n"); |
|
329 iTest->Printf(KUpdateOutputFormat, updateResult / 1000000, (updateResult / 1000) % 1000); |
|
330 |
|
331 _LIT(KDeleteOutputFormat,"Deleting 1 contact took: %d s %03d\n"); |
|
332 iTest->Printf(KDeleteOutputFormat, deleteResult / 1000000, (deleteResult / 1000) % 1000); |
|
333 } |