|
1 /** |
|
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 /** |
|
21 @file |
|
22 @internalComponent |
|
23 @released |
|
24 */ |
|
25 |
|
26 |
|
27 #ifndef __PLTABLES_H__ |
|
28 #define __PLTABLES_H__ |
|
29 |
|
30 #include "cntsqlprovider.h" |
|
31 #include "persistencelayer.h" |
|
32 #include "clplcontactproperties.h" |
|
33 #include <cntdef.h> |
|
34 #include <cntitem.h> |
|
35 #include <cntfldst.h> |
|
36 |
|
37 #include <sqldb.h> |
|
38 #include <e32hashtab.h> |
|
39 |
|
40 |
|
41 /** |
|
42 The CPplTableBase class forms the base class for all SQLite tables in the |
|
43 Persistence Layer. It implements default behaviour for some basic operations. |
|
44 |
|
45 It holds member variables for the database and SQL statements representing the |
|
46 4 CRUD operations. The ReadL function is virtual with a default implementation |
|
47 that does nothing so that it can be overridden in the derived classes, as |
|
48 necessary. This is to allow the read operation to be performed on all classes |
|
49 in the same manner, even when in cases where there is nothing to be read. In |
|
50 this way, all table classes can be treated the same. This is to facilitate the |
|
51 use of the composite design pattern. |
|
52 */ |
|
53 NONSHARABLE_CLASS(CPplTableBase) : public CBase |
|
54 { |
|
55 public: |
|
56 virtual void CreateInDbL(CContactItem& aItem) = 0; |
|
57 virtual void UpdateL(const CContactItem& aItem) = 0; |
|
58 virtual void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred) = 0; |
|
59 virtual void CreateTableL() = 0; |
|
60 }; |
|
61 |
|
62 |
|
63 /** |
|
64 The CPplContactTable class has a dual nature, caused by inheritance from two |
|
65 interfaces: MPplContactItemPersistor and MLplPersistenceBroker. |
|
66 |
|
67 MPplContactItemPersistor inheritance makes the CPplContactTable a normal table |
|
68 capable of perfoming five basic operations (Create, Read, Update, Delete and |
|
69 ChangeType) when called from the parent table. |
|
70 |
|
71 MLplPersistenceBroker is a public interface responsible for carrying out the |
|
72 basic operations. It is exposed to the users of Persistence Layer making the |
|
73 RPplContactTable an entry point for these operations. |
|
74 |
|
75 As a result ContactTable appears twice in the tree structure of tables: once as |
|
76 a root table (MLplPersistenceBroker inteface) and second time as a child of |
|
77 Email table (MPplContactItemPersistor inteface). |
|
78 |
|
79 The Contact table is responsible for saving header information for all the |
|
80 fields in a contact and the values of most of the fields. Four C/BLOB fields |
|
81 are used for this purpose. |
|
82 |
|
83 Header information (including label and content type of the fields) is stored in |
|
84 in the binary_fields_header and text_fields_header columns. |
|
85 |
|
86 The binary_fields column accomodates the binary values of the fields (such as |
|
87 pictures or sounds). |
|
88 |
|
89 All human readable text values go to the text_fields column. This is particularly |
|
90 useful for searching through all textual fields of contacts. |
|
91 */ |
|
92 NONSHARABLE_CLASS(CPplContactTable) : public CPplTableBase |
|
93 { |
|
94 public: |
|
95 class THintField |
|
96 { |
|
97 friend class CPplContactTable; |
|
98 public: |
|
99 THintField(); |
|
100 void UpdateHintL(const CContactItemField& aField, const RArray<TUid>& aCustFiltFields); |
|
101 |
|
102 |
|
103 TUint16 ExtHint(); |
|
104 TInt8 Hint(); |
|
105 private: |
|
106 THintField(TUint16 aExtHint, TUint8 aHint); |
|
107 |
|
108 private: |
|
109 TInt iValue; |
|
110 }; |
|
111 |
|
112 |
|
113 public: |
|
114 static CPplContactTable* NewL(RSqlDatabase& aDatabase, CLplContactProperties& aProperties); |
|
115 static CPplContactTable* NewLC(RSqlDatabase& aDatabase, CLplContactProperties& aProperties); |
|
116 void CreateInDbL(CContactItem& aItem); |
|
117 void CreateInDbL(CContactItem& aItem, TUint aSessionId); |
|
118 |
|
119 void UpdateL(const CContactItem& aItem); |
|
120 void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred); |
|
121 CContactItem* DeleteLC(TContactItemId aItemId, TBool& aLowDiskErrorOccurred); |
|
122 void CreateTableL(); |
|
123 |
|
124 void ChangeTypeL(TContactItemId aItemId, TUid aNewType); |
|
125 TInt NameFieldUid(const CContactItemField& nameField); |
|
126 |
|
127 TBool IsTableEmptyL(); |
|
128 CContactIdArray& CardTemplateIdsL(); |
|
129 TContactItemId OwnCardIdL(); |
|
130 void SetOwnCardIdL(TContactItemId aId); |
|
131 |
|
132 ~CPplContactTable(); |
|
133 |
|
134 |
|
135 private: |
|
136 CPplContactTable(RSqlDatabase& aDatabase, CLplContactProperties& aProps); |
|
137 void ConstructL(); |
|
138 void WriteContactItemL(const CContactItem& aItem, TCntSqlStatement aType); |
|
139 void UpdateTemplateAccessCounterL(TContactItemId aTemplateRefId, TBool aIncrement); |
|
140 void GetTypeFlagFields(TInt aTypeFlags, TUid& aType, TUint& aAttributes, TUint& aHintFields); |
|
141 TInt GenerateTypeFlags(TUid aType, TUint aAttributes, TUint aHintFields); |
|
142 TUint NumDigits(TInt aNum); |
|
143 |
|
144 private: |
|
145 CLplContactProperties& iProperties; |
|
146 CCntSqlStatement* iInsertStmnt; |
|
147 CCntSqlStatement* iDeleteSelectStmnt; |
|
148 CCntSqlStatement* iAccessCountUpdateStmnt; |
|
149 CCntSqlStatement* iUpdateFlagsStmnt; |
|
150 CCntSqlStatement* iUpdateStmnt; |
|
151 CCntSqlStatement* iDeleteStmnt; |
|
152 RHashMap<TInt, TPtrC> iFieldMap; |
|
153 RSqlDatabase& iDatabase; |
|
154 |
|
155 CContactIdArray* iCardTemplateIds; |
|
156 }; |
|
157 |
|
158 /** |
|
159 The CPplCommAddrTable class is used to store all communication addresses in a |
|
160 contact item. This includes telephone/fax numbers, email addresses and SIP |
|
161 addresses. |
|
162 |
|
163 Email and SIP addresses are stored as-is but telephone/fax numbers are hashed |
|
164 in this table. This is because in the text field in the contact table, telephone |
|
165 numbers are stored as text. This provides great flexibility for the users as they |
|
166 can use any symbol in their telephone number fields, such as '+','(',')', spaces |
|
167 or even words like 'ext.' or 'emergency only'. However, this form of information |
|
168 storage present a big problem in the phone matching use case i.e. when the |
|
169 Contacts Model should quickly find a contact with the given phone number in it. |
|
170 |
|
171 This problem is solved with the hashing mechanism. Each time the user creates a |
|
172 new phone field or changes the existing one the hash value is calculated and |
|
173 saved in the phone table. The hash value is calculated with the help of the |
|
174 cntphone plugin, which parses the text containing the telephone number and tries |
|
175 to find all the informative digits and symbols. |
|
176 |
|
177 Originally the hash value covered only last seven digits of the phone number and |
|
178 the TInt column was enough to store the hash. Later the value was extended and |
|
179 now it is stored in two TInt columns to provide data backward compatibility with |
|
180 previous versions of the Contacts Model. |
|
181 |
|
182 The comm_addr table contains a private helper class TMatch that represents the |
|
183 hash value and an enumeration to specify type of communication address. |
|
184 */ |
|
185 NONSHARABLE_CLASS(CPplCommAddrTable) : public CPplTableBase |
|
186 { |
|
187 private: |
|
188 class TMatch |
|
189 { |
|
190 public: |
|
191 TMatch(); |
|
192 |
|
193 static TInt32 CreateHashL(const TDesC& aPhoneNumberString, TInt aMatchLength, TInt& aNumPhoneDigits); |
|
194 static void StripOutNonDigitChars(TDes& aText); |
|
195 static TInt32 PadOutPhoneMatchNumber(TInt32& aPhoneNumber,TInt aPadOutLength); |
|
196 static TBool Equals (const TMatch& aRMatch ,const TMatch& aLMatch); |
|
197 inline TBool operator==(const TMatch &aMatch) const; |
|
198 |
|
199 public: |
|
200 TInt32 iLowerSevenDigits; |
|
201 TInt32 iUpperDigits; |
|
202 TInt iNumLowerDigits; |
|
203 TInt iNumUpperDigits; |
|
204 }; |
|
205 |
|
206 public: |
|
207 // defines type of communication address. |
|
208 // !! the values these represent are persisted in the database !! |
|
209 // !! do not change the order -- add new ones to the bottom !! |
|
210 // !! changing these values could break data compatibility !! |
|
211 enum TCommAddrType |
|
212 { |
|
213 EPhoneNumber, |
|
214 EEmailAddress, |
|
215 ESipAddress |
|
216 }; |
|
217 |
|
218 public: |
|
219 static CPplCommAddrTable* NewL(RSqlDatabase& aDatabase, CLplContactProperties& aProperties); |
|
220 static CPplCommAddrTable* NewLC(RSqlDatabase& aDatabase, CLplContactProperties& aProperties); |
|
221 void CreateInDbL(CContactItem& aItem); |
|
222 void UpdateL(const CContactItem& aItem); |
|
223 void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred); |
|
224 void CreateTableL(); |
|
225 |
|
226 CContactIdArray* MatchPhoneNumberL(const TDesC& aNumber, const TInt aMatchLengthFromRight); |
|
227 CContactIdArray* MatchEmailAddressL(const TDesC& aEmailAddr); |
|
228 CContactIdArray* MatchSipAddressL(const TDesC& aSipAddr); |
|
229 |
|
230 ~CPplCommAddrTable(); |
|
231 |
|
232 private: |
|
233 void ConstructL(); |
|
234 CPplCommAddrTable(RSqlDatabase& aDatabase, CLplContactProperties& iProperties); |
|
235 void RemoveNonUpdatedAddrsL(RArray<TMatch>& aNewPhones, RArray<TPtrC>& aNewEmails, RArray<TPtrC>& aNewSips, |
|
236 RArray<TInt>& aFreeCommAddrIds, const TInt aItemId); |
|
237 void DoUpdateCommAddrsL(RArray<TMatch>& aNewPhones, RArray<TPtrC>& aNewEmails, RArray<TPtrC>& aNewSips, |
|
238 RArray<TInt>& aFreeCommAddrIds, const TInt aItemId); |
|
239 void DeleteSingleCommAddrL(TInt aCommAddrId, TBool& aLowDiskErrorOccurred); |
|
240 void DoPhoneNumWriteOpL(const CPplCommAddrTable::TMatch& aPhoneNum, TCntSqlStatement aType, TInt aCntId); |
|
241 void DoPhoneNumWriteOpL(const CPplCommAddrTable::TMatch& aPhoneNum, TCntSqlStatement aType, TInt aCntId, |
|
242 TInt aCommAddrId); |
|
243 void DoNonPhoneWriteOpL(const TDesC& aAddress, TCntSqlStatement aType, TInt aCntId, |
|
244 TCommAddrType aAddrType); |
|
245 void DoNonPhoneWriteOpL(const TDesC& aAddress, TCntSqlStatement aType, TInt aCntId, |
|
246 TCommAddrType aAddrType, TInt aCommAddrId); |
|
247 CContactIdArray* MatchNonPhoneAddrL(const TDesC& aCommAddr, TCommAddrType aAddrType); |
|
248 CPplCommAddrTable::TMatch CreatePaddedPhoneDigitsL(const TDesC& aNumber, const TInt aNumLowerDigits, |
|
249 const TInt aNumUpperDigits); |
|
250 CPplCommAddrTable::TMatch CreatePhoneMatchNumberL(const TDesC& aText, TInt aLowerMatchLength, |
|
251 TInt aUpperMatchLength); |
|
252 |
|
253 private: |
|
254 CLplContactProperties& iProperties; |
|
255 CCntSqlStatement* iInsertStmnt; |
|
256 CCntSqlStatement* iWholeSelectStmnt; |
|
257 CCntSqlStatement* iMatchSelectStmnt; |
|
258 CCntSqlStatement* iUpdateStmnt; |
|
259 CCntSqlStatement* iAllForItemDeleteStmnt; |
|
260 CCntSqlStatement* iSingleDeleteStmnt; |
|
261 RSqlDatabase& iDatabase; |
|
262 }; |
|
263 |
|
264 |
|
265 /** |
|
266 The CPplGroupsTable class provides a mapping between contact groups and members |
|
267 of those groups. The groups table provides two fields: contact_group_id and |
|
268 contact_group_member_id. Both of these are foreign keys referencing the contact_id |
|
269 field of the contact table. Using these two fields, lookup can be performed in |
|
270 either direction: members of a group; groups of which item is a member. |
|
271 */ |
|
272 NONSHARABLE_CLASS(CPplGroupsTable) : public CPplTableBase |
|
273 { |
|
274 public: |
|
275 static CPplGroupsTable* NewL(RSqlDatabase& aDatabase); |
|
276 static CPplGroupsTable* NewLC(RSqlDatabase& aDatabase); |
|
277 void CreateInDbL(CContactItem& aItem); |
|
278 void ReadL(CContactItem& aItem); |
|
279 void UpdateL(const CContactItem& aItem); |
|
280 void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred); |
|
281 void CreateTableL(); |
|
282 ~CPplGroupsTable(); |
|
283 |
|
284 private: |
|
285 void ConstructL(); |
|
286 CContactIdArray* GetListForItemL(TContactItemId aItemId, TBool aIsGroup); |
|
287 void DeleteItemL(TContactItemId aItemId, TBool& aLowDiskErrorOccurred); |
|
288 CPplGroupsTable(RSqlDatabase& aDatabase); |
|
289 void WriteGroupMembersL(const CContactItem& aGroup); |
|
290 |
|
291 private: |
|
292 CCntSqlStatement* iInsertStmnt; |
|
293 CCntSqlStatement* iSelectGroupsStmnt; |
|
294 CCntSqlStatement* iSelectMembersStmnt; |
|
295 CCntSqlStatement* iDeleteStmnt; |
|
296 CCntSqlStatement* iCountContactsStmnt; |
|
297 |
|
298 RSqlDatabase& iDatabase; |
|
299 }; |
|
300 |
|
301 |
|
302 /** |
|
303 This class holds a set of contact database preferences and is used in conjunction |
|
304 with the CPplPreferencesPersistor class. |
|
305 */ |
|
306 NONSHARABLE_CLASS(RCntPreferences) |
|
307 { |
|
308 public: |
|
309 TUint DataSchemaVersion() const; |
|
310 TUint DatabaseUid() const; |
|
311 TTime CreationDate() const; |
|
312 TUint PreferCardTemplateId() const; |
|
313 RContactViewSortOrder& PreferredSortOrder(); |
|
314 RCntPreferences(); |
|
315 void Close(); |
|
316 void SetDataSchemaVersion(TUint aDbSchemaVersion); |
|
317 void SetDatabaseUid(TUint aDbUid); |
|
318 void SetCreationDate(TTime aCreationDate); |
|
319 void SetFieldTypeFixsize(TUint aFieldTypeFixsize); |
|
320 void SetPreferredSortOrderL(const RContactViewSortOrder& aSortOrder); |
|
321 void SetPreferCardTemplateId(TUint aTemplateId); |
|
322 |
|
323 private: |
|
324 TUint iDbSchemaVersion; |
|
325 TUint iDbUid; |
|
326 TTime iCreationDate; |
|
327 TUint iPreferCardTemplateId; |
|
328 RContactViewSortOrder iSortOrder; |
|
329 }; |
|
330 |
|
331 /** |
|
332 The CPplPreferencesPersistor class is used to store contact database preferences, |
|
333 as represented by the RCntPreferences class and, currently, stored in the |
|
334 preferences table in the SQLite database. As this information is different from |
|
335 the rest of the data in that it is not contacts data but metadata about the |
|
336 database itself, it is treated differently. Hence, this class is called a persistor |
|
337 and not a table class to emphasise the differences and to provide the flexibility |
|
338 to change the way the preferences information is persist in the future if this is |
|
339 desired. |
|
340 |
|
341 */ |
|
342 NONSHARABLE_CLASS(CPplPreferencesPersistor) : public CBase |
|
343 { |
|
344 public: |
|
345 static CPplPreferencesPersistor* NewL(RSqlDatabase& aDatabase); |
|
346 ~CPplPreferencesPersistor(); |
|
347 |
|
348 void CreateTableL(); |
|
349 |
|
350 // getters |
|
351 TDesC DataSchemaVersion() const; |
|
352 TInt64 MachineIdL(); |
|
353 TTime CreationDateL(); |
|
354 TContactItemId PreferredCardTemplateIdL(); |
|
355 const CArrayFix<CContactDatabase::TSortPref>& PreferredSortOrderL(); |
|
356 TPtrC DatabaseUidL(); |
|
357 |
|
358 // setters |
|
359 void SetMachineIdL(TInt64 aMachineId); |
|
360 void SetPreferredCardTemplateIdL(TContactItemId aTemplateId); |
|
361 void SetPreferredSortOrderL(CArrayFix<CContactDatabase::TSortPref>* aSortOrder); |
|
362 |
|
363 // utility methods |
|
364 void SetGuidL(CContactItem& aContact, TBool& aCompressed); |
|
365 |
|
366 private: |
|
367 CPplPreferencesPersistor(RSqlDatabase& aDatabase); |
|
368 void ConstructL(); |
|
369 void FirstWriteToTableL(); |
|
370 void GenerateMachineUniqueID(); |
|
371 void ReadInStateL(); |
|
372 void PersistStateL(const TDesC& aParam, TInt aValue); |
|
373 |
|
374 private: |
|
375 RSqlDatabase& iDatabase; |
|
376 CCntSqlStatement* iUpdateStmnt; |
|
377 TUint iMachineId; // machine id |
|
378 TTime iCreationDate; // creation data |
|
379 TBuf<40> iUidString; //unique id |
|
380 TContactItemId iPreferCardTemplateId; // template |
|
381 CArrayFix<CContactDatabase::TSortPref>* iSortOrderPrefs; // sort order |
|
382 }; |
|
383 |
|
384 #endif |