summaryrefslogtreecommitdiffstats
path: root/plugins/contacts/symbian/contactsmodel/cntplsql/inc/pltables.h
blob: 94f85cf0fe00ba1d0d9004d410968cbaf806d160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/*
* Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
* Contact: http://www.qt-project.org/legal
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/




/**
 @file
 @internalComponent
 @released
*/


#ifndef __PLTABLES_H__
#define __PLTABLES_H__

#include "cntsqlprovider.h"
#include "persistencelayer.h"
#include "clplcontactproperties.h"
#include <cntdef.h>
#include <cntitem.h>
#include <cntfldst.h>
#include <f32file.h>
#include <e32std.h>

#include <sqldb.h>
#include <e32hashtab.h>


/**
The CPplTableBase class forms the base class for all SQLite tables in the
Persistence Layer. It implements default behaviour for some basic operations.

It holds member variables for the database and SQL statements representing the
4 CRUD operations. The ReadL function is virtual with a default implementation
that does nothing so that it can be overridden in the derived classes, as
necessary. This is to allow the read operation to be performed on all classes
in the same manner, even when in cases where there is nothing to be read. In
this way, all table classes can be treated the same. This is to facilitate the
use of the composite design pattern.
*/
NONSHARABLE_CLASS(CPplTableBase) : public CBase
	{
public:
	virtual void CreateInDbL(CContactItem& aItem) = 0;
	virtual void UpdateL(const CContactItem& aItem) = 0;
	virtual void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred) = 0;
	virtual void CreateTableL() = 0;
	};


/**
The CPplContactTable class has a dual nature, caused by inheritance from two
interfaces: MPplContactItemPersistor and MLplPersistenceBroker.

MPplContactItemPersistor inheritance makes the CPplContactTable a normal table
capable of perfoming five basic operations (Create, Read, Update, Delete and
ChangeType) when called from the parent table.

MLplPersistenceBroker is a public interface responsible for carrying out the
basic operations.  It is exposed to the users of Persistence Layer making the
RPplContactTable an entry point for these operations.

As a result ContactTable appears twice in the tree structure of tables: once as
a root table (MLplPersistenceBroker inteface) and second time as a child of
Email table (MPplContactItemPersistor inteface).

The Contact table is responsible for saving header information for all the
fields in a contact and the values of most of the fields. Four C/BLOB fields
are used for this purpose.

Header information (including label and content type of the fields) is stored in
in the binary_fields_header and text_fields_header columns.

The binary_fields column accomodates the binary values of the fields (such as
pictures or sounds).

All human readable text values go to the text_fields column. This is particularly
useful for searching through all textual fields of contacts.
*/
NONSHARABLE_CLASS(CPplContactTable) : public CPplTableBase
	{
public:
	class THintField
		{
	friend class CPplContactTable;
	public:
		THintField();
		void UpdateHintL(const CContactItemField& aField, const RArray<TUid>& aCustFiltFields);


		TUint16 ExtHint();
		TInt8 Hint();
	private:
		THintField(TUint16 aExtHint, TUint8 aHint);

	private:
		TInt iValue;
		};


public:
	static CPplContactTable* NewL(RSqlDatabase& aDatabase, CLplContactProperties& aProperties);
	static CPplContactTable* NewLC(RSqlDatabase& aDatabase, CLplContactProperties& aProperties);
	void CreateInDbL(CContactItem& aItem);
	void CreateInDbL(CContactItem& aItem, TUint aSessionId);

	void UpdateL(const CContactItem& aItem);
	void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred);
	CContactItem* DeleteLC(TContactItemId  aItemId, TBool& aLowDiskErrorOccurred);
	void CreateTableL();

	void ChangeTypeL(TContactItemId aItemId, TUid aNewType);
	TInt NameFieldUid(const CContactItemField& nameField);

	TBool IsTableEmptyL();
	CContactIdArray& CardTemplateIdsL();
	TContactItemId OwnCardIdL();
    void SetOwnCardIdL(TContactItemId aId, TBool aPersist = ETrue);	
    
	~CPplContactTable();
	

private:
	CPplContactTable(RSqlDatabase& aDatabase, CLplContactProperties& aProps);
	void ConstructL();
	void WriteContactItemL(const CContactItem& aItem, TCntSqlStatement aType);
	void UpdateTemplateAccessCounterL(TContactItemId aTemplateRefId, TBool aIncrement);
	void GetTypeFlagFields(TInt aTypeFlags, TUid& aType, TUint& aAttributes, TUint& aHintFields);
	TInt GenerateTypeFlags(TUid aType, TUint aAttributes, TUint aHintFields);
	TUint NumDigits(TInt aNum);
	
private:
	CLplContactProperties& iProperties;
	CCntSqlStatement* iInsertStmnt;
	CCntSqlStatement* iDeleteSelectStmnt;
	CCntSqlStatement* iAccessCountUpdateStmnt;
	CCntSqlStatement* iUpdateFlagsStmnt;
	CCntSqlStatement* iUpdateStmnt;
	CCntSqlStatement* iDeleteStmnt;
	RHashMap<TInt, TPtrC> iFieldMap;
	RSqlDatabase&  iDatabase;
	RFs iFs;
	TPath iImagesDirPath;
	
	CContactIdArray* iCardTemplateIds;
	TContactItemId iOwnCardId;
	};

/**
The CPplCommAddrTable class is used to store all communication addresses in a
contact item. This includes telephone/fax numbers, email addresses and SIP
addresses.

Email and SIP addresses are stored as-is but telephone/fax numbers are hashed
in this table. This is because in the text field in the contact table, telephone
numbers are stored as text. This provides great flexibility for the users as they
can use any symbol in their telephone number fields, such as '+','(',')', spaces
or even words like 'ext.' or 'emergency only'. However, this form of information
storage present a big problem in the phone matching use case i.e. when the
Contacts Model should quickly find a contact with the given phone number in it.

This problem is solved with the hashing mechanism.  Each time the user creates a
new phone field or changes the existing one the hash value is calculated and
saved in the phone table.  The hash value is calculated with the help of the
cntphone plugin, which parses the text containing the telephone number and tries
to find all the informative digits and symbols.

Originally the hash value covered only last seven digits of the phone number and
the TInt column was enough to store the hash.  Later the value was extended and
now it is stored in two TInt columns to provide data backward compatibility with
previous versions of the Contacts Model.

The comm_addr table contains a private helper class TMatch that represents the
hash value and an enumeration to specify type of communication address.
*/
NONSHARABLE_CLASS(CPplCommAddrTable) : public CPplTableBase
	{
private:
	class TMatch
		{
	public:
		TMatch();

		static TInt32 CreateHashL(const TDesC& aPhoneNumberString, TInt aMatchLength, TInt& aNumPhoneDigits);
		static void StripOutNonDigitChars(TDes& aText);
		static TInt32 PadOutPhoneMatchNumber(TInt32& aPhoneNumber,TInt aPadOutLength);
		static TBool Equals (const TMatch& aRMatch ,const TMatch& aLMatch);
		inline TBool operator==(const TMatch &aMatch) const;

	public:
		TInt32 iLowerSevenDigits;
		TInt32 iUpperDigits;
		TInt iNumLowerDigits;
		TInt iNumUpperDigits;
		};

public:
	// defines type of communication address.
	// !! the values these represent are persisted in the database  !!
	// !!  do not change the order -- add new ones to the bottom    !!
	// !!   changing these values could break data compatibility    !!
	enum TCommAddrType
		{
		EPhoneNumber,
		EEmailAddress,
		ESipAddress
		};

	// defines extra_type_info of communication address.
	// !! the values these represent are persisted in the database  !!
	// !!  do not change the order -- add new ones to the bottom    !!
	// !!   changing these values could break data compatibility    !!
	enum TCommAddrExtraInfoType
	    {
	    ENonMobileNumber = 0,
	    EMobileNumber
	    };


public:
	static CPplCommAddrTable* NewL(RSqlDatabase& aDatabase, CLplContactProperties& aProperties);
	static CPplCommAddrTable* NewLC(RSqlDatabase& aDatabase, CLplContactProperties& aProperties);
	void CreateInDbL(CContactItem& aItem);
	void UpdateL(const CContactItem& aItem);
	void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred);
	void CreateTableL();

	CContactIdArray* MatchPhoneNumberL(const TDesC& aNumber, const TInt aMatchLengthFromRight);
	CContactIdArray* MatchEmailAddressL(const TDesC& aEmailAddr);
	CContactIdArray* MatchSipAddressL(const TDesC& aSipAddr);

	~CPplCommAddrTable();

private:
	void ConstructL();
	CPplCommAddrTable(RSqlDatabase& aDatabase, CLplContactProperties& iProperties);
	void RemoveNonUpdatedAddrsL(RArray<TMatch>& aNewPhones, RArray<TPtrC>& aNewEmails, RArray<TPtrC>& aNewSips, 
							RArray<TInt>& aFreeCommAddrIds, const TInt aItemId, 
							CPplCommAddrTable::TCommAddrExtraInfoType aExtraInfoType);
	void DoUpdateCommAddrsL(RArray<TMatch>& aNewPhones, RArray<TPtrC>& aNewEmails, RArray<TPtrC>& aNewSips, 
						    RArray<TInt>& aFreeCommAddrIds, const TInt aItemId, 
						    CPplCommAddrTable::TCommAddrExtraInfoType aExtraInfoType = ENonMobileNumber);
	void DeleteSingleCommAddrL(TInt aCommAddrId, TBool& aLowDiskErrorOccurred);
	void DoPhoneNumWriteOpL(const CPplCommAddrTable::TMatch& aPhoneNum, TCntSqlStatement aType, TInt aCntId);
	void DoPhoneNumWriteOpL(const CPplCommAddrTable::TMatch& aPhoneNum, TCntSqlStatement aType, TInt aCntId, TInt aCommAddrId,
							CPplCommAddrTable::TCommAddrExtraInfoType aExtraInfoType = ENonMobileNumber);
	void DoNonPhoneWriteOpL(const TDesC& aAddress, TCntSqlStatement aType, TInt aCntId, 
							TCommAddrType aAddrType);
	void DoNonPhoneWriteOpL(const TDesC& aAddress, TCntSqlStatement aType, TInt aCntId, 
							TCommAddrType aAddrType, TInt aCommAddrId);
	CContactIdArray* MatchNonPhoneAddrL(const TDesC& aCommAddr, TCommAddrType aAddrType);
	CPplCommAddrTable::TMatch CreatePaddedPhoneDigitsL(const TDesC& aNumber, const TInt aNumLowerDigits, 
							const TInt aNumUpperDigits);
	CPplCommAddrTable::TMatch CreatePhoneMatchNumberL(const TDesC& aText, TInt aLowerMatchLength, 
							TInt aUpperMatchLength);

private:
	CLplContactProperties& iProperties;
	CCntSqlStatement* iInsertStmnt;
	CCntSqlStatement* iWholeSelectStmnt;
	CCntSqlStatement* iMatchSelectStmnt;
	CCntSqlStatement* iUpdateStmnt;
	CCntSqlStatement* iAllForItemDeleteStmnt;
	CCntSqlStatement* iSingleDeleteStmnt;
	RSqlDatabase&  iDatabase;
	TBool iDynamicMatch;
	};


/**
The CPplGroupsTable class provides a mapping between contact groups and members
of those groups. The groups table provides two fields: contact_group_id and
contact_group_member_id. Both of these are foreign keys referencing the contact_id
field of the contact table. Using these two fields, lookup can be performed in 
either direction: members of a group; groups of which item is a member.
*/
NONSHARABLE_CLASS(CPplGroupsTable) : public CPplTableBase
	{
public:
	static CPplGroupsTable* NewL(RSqlDatabase& aDatabase);
	static CPplGroupsTable* NewLC(RSqlDatabase& aDatabase);
	void CreateInDbL(CContactItem& aItem);
	void ReadL(CContactItem& aItem);
	void UpdateL(const CContactItem& aItem);
	void DeleteL(const CContactItem& aItem, TBool& aLowDiskErrorOccurred);
	void CreateTableL();
	~CPplGroupsTable();

private:
	void ConstructL();
	CContactIdArray* GetListForItemL(TContactItemId aItemId, TBool aIsGroup);
	void DeleteItemL(TContactItemId aItemId, TBool& aLowDiskErrorOccurred);
	CPplGroupsTable(RSqlDatabase& aDatabase);
	void WriteGroupMembersL(const CContactItem& aGroup);

private:
	CCntSqlStatement* iInsertStmnt;
	CCntSqlStatement* iSelectGroupsStmnt;
	CCntSqlStatement* iSelectMembersStmnt;
	CCntSqlStatement* iDeleteStmnt;
	CCntSqlStatement* iCountContactsStmnt;
	
	RSqlDatabase&  iDatabase;
	};


/**
This class holds a set of contact database preferences and is used in conjunction
with the CPplPreferencesPersistor class.
*/
NONSHARABLE_CLASS(RCntPreferences)
	{
public:
	TUint DataSchemaVersion() const;
	TUint DatabaseUid() const;
	TTime CreationDate() const;
	TUint PreferCardTemplateId() const;	
	RContactViewSortOrder& PreferredSortOrder();
	RCntPreferences();
	void Close();
	void SetDataSchemaVersion(TUint aDbSchemaVersion);
	void SetDatabaseUid(TUint aDbUid);
	void SetCreationDate(TTime aCreationDate);
	void SetFieldTypeFixsize(TUint aFieldTypeFixsize);
	void SetPreferredSortOrderL(const RContactViewSortOrder& aSortOrder);
	void SetPreferCardTemplateId(TUint aTemplateId);	

private:
	TUint iDbSchemaVersion;
	TUint iDbUid;
	TTime iCreationDate;
	TUint iPreferCardTemplateId;	
	RContactViewSortOrder iSortOrder;
	};

/**
The CPplPreferencesPersistor class is used to store contact database preferences,
as represented by the RCntPreferences class and, currently, stored in the 
preferences table in the SQLite database. As this information is different from
the rest of the data in that it is not contacts data but metadata about the 
database itself, it is treated differently. Hence, this class is called a persistor
and not a table class to emphasise the differences and to provide the flexibility
to change the way the preferences information is persist in the future if this is
desired.

*/
NONSHARABLE_CLASS(CPplPreferencesPersistor) : public CBase
	{
public:
	static CPplPreferencesPersistor* NewL(RSqlDatabase& aDatabase);
	~CPplPreferencesPersistor();
	
	void CreateTableL();

    // getters
	TDesC DataSchemaVersion() const;
	TInt64 MachineIdL();
	TTime CreationDateL();
	TContactItemId PreferredCardTemplateIdL();	
	const CArrayFix<CContactDatabase::TSortPref>& PreferredSortOrderL();
	TPtrC DatabaseUidL();	
		
	// setters 	
	void SetMachineIdL(TInt64 aMachineId);
	void SetPreferredCardTemplateIdL(TContactItemId aTemplateId);
	void SetPreferredSortOrderL(CArrayFix<CContactDatabase::TSortPref>* aSortOrder);	 
	
	// utility methods
	void SetGuidL(CContactItem& aContact, TBool& aCompressed);
	
private:
	CPplPreferencesPersistor(RSqlDatabase& aDatabase);
	void ConstructL();
	void FirstWriteToTableL();
	void GenerateMachineUniqueID();
	void ReadInStateL();
	void PersistStateL(const TDesC& aParam, TInt aValue);

private:
	RSqlDatabase& iDatabase;
	CCntSqlStatement* iUpdateStmnt;
	TUint iMachineId;        // machine id    
	TTime iCreationDate;     // creation data
	TBuf<40> iUidString;     //unique id  
	TContactItemId iPreferCardTemplateId;   // template	
	CArrayFix<CContactDatabase::TSortPref>* iSortOrderPrefs;		 // sort order
	};

#endif