phonebookengines/contactsmodel/cntplsql/inc/pltables.h
changeset 0 e686773b3f54
child 24 0ba2181d7c28
child 26 0d28c1c5b6dd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/contactsmodel/cntplsql/inc/pltables.h	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,384 @@
+/**
+* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* 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 <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);	
+    
+	~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;
+	
+	CContactIdArray* iCardTemplateIds;
+	};
+
+/**
+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
+		};
+
+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);
+	void DoUpdateCommAddrsL(RArray<TMatch>& aNewPhones, RArray<TPtrC>& aNewEmails, RArray<TPtrC>& aNewSips, 
+						    RArray<TInt>& aFreeCommAddrIds, const TInt aItemId);
+	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);
+	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;
+	};
+
+
+/**
+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