messagingfw/msgsrvnstore/server/src/msvsearchsortquery.cpp
changeset 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgsrvnstore/server/src/msvsearchsortquery.cpp	Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,573 @@
+
+// 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:
+//
+
+#include <msvsearchsortquery.h>
+#include <msvids.h>
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS  
+#include "msvsearchsortconstants.h"
+#include "msvconsts.h"
+#endif
+/** 
+Factory function which returns a pointer of CMsvSearchSortQuery to create a search-sort query.
+@param NONE 
+@return If the function succeeds, this is a pointer to a newly allocated 
+and initialised object. 
+@leave KErrNoMemory A memory allocation failed 
+*/
+EXPORT_C CMsvSearchSortQuery* CMsvSearchSortQuery::NewL()
+	{
+	CMsvSearchSortQuery* self = NewLC();
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+/** 
+Factory function which returns a pointer of CMsvSearchSortQuery to create a search-sort query.
+@param NONE 
+@return If the function succeeds, this is a pointer to a newly allocated 
+and initialised object. 
+@leave KErrNoMemory A memory allocation failed 
+*/
+EXPORT_C CMsvSearchSortQuery* CMsvSearchSortQuery::NewLC()
+	{
+	CMsvSearchSortQuery* self = new(ELeave) CMsvSearchSortQuery();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+/**
+Second phase construction, allocating memory for query table.
+@leave KErrNoMemory A memory allocation failed 
+*/
+void CMsvSearchSortQuery::ConstructL()
+	{
+	iQueryTable = new(ELeave) TMsvQueryTable[KMaxLevelOfSearchAndSort];
+	}
+
+
+/**
+Constructor
+*/
+CMsvSearchSortQuery::CMsvSearchSortQuery()
+	{
+	iParentId = KMsvGlobalInBoxIndexEntryId;
+	iCaseSensitive = EFalse;
+	iWholeWord = EFalse;
+	iWildCardCharacter = EFalse;
+	iExplicitSort = EFalse;
+	iIsSearchQuery = EFalse;
+	iSubFolderSearch = EFalse;
+	iQueryCount = 0;
+	//if sort is not provided by query, there won't any sorting. so it's assigned to '0'
+	iSortOnMessagePart = TMsvMessagePart(0);
+	iSortOrder = EMsvSortAscending;
+	iSearchSortResultType = EMsvResultAsTMsvId;
+	iCountMultilevelSort = 0;
+	iQueryId = 0;
+	}
+
+/** 
+Destructor.
+*/
+EXPORT_C CMsvSearchSortQuery::~CMsvSearchSortQuery()
+	{
+	//delete iQueryTable
+	delete [] iQueryTable;
+	}
+
+/**
+set aParentId. search and/or sort will be done this aParentId.
+@param aParentId  Search and/or sort operation can be performed on a specified root, folder or service. 
+*/
+EXPORT_C void CMsvSearchSortQuery::SetParentId(const TMsvId aParentId)
+	{
+	iParentId = aParentId;
+	}
+
+/**
+Set Case Sensitive search option.
+@param aFlag set ETrue or EFalse
+*/
+EXPORT_C void CMsvSearchSortQuery::SetCaseSensitiveOption (TBool aCaseSensitive)
+	{
+	iCaseSensitive = aCaseSensitive;
+	}
+
+/**
+Set Whole word search option.
+@param aFlag set ETrue or EFalse
+*/
+EXPORT_C void CMsvSearchSortQuery::SetWholeWord (TBool aWholeWord)
+	{
+	iWholeWord = aWholeWord;
+	}
+
+/**
+Enable wild card character search.
+@param aFlag set ETrue or EFalse
+*/
+EXPORT_C void CMsvSearchSortQuery::SetWildCardSearch (TBool aWildCard)
+	{
+	iWildCardCharacter = aWildCard;
+	}
+
+/**
+Client expects search sort results as TMsvId or TMsvEntry
+@param aResultType  set result type as TMsvId or TMsvEntry
+*/
+
+EXPORT_C void CMsvSearchSortQuery::SetResultType (TMsvSearchSortResultType aSearchSortResultType)
+	{
+	iSearchSortResultType = aSearchSortResultType;
+	}
+
+/**
+Enable subfolder search.
+@param aFlag set ETrue or EFalse
+*/
+EXPORT_C void CMsvSearchSortQuery::SetSubFolderSearch (TBool aSubFolderSearch)
+	{
+	iSubFolderSearch = aSubFolderSearch;
+	}
+
+
+/**
+Adds the search options to the search-sort query. 
+This function is used when the message part requires descriptor value during 
+search-sort operation.
+
+@param aMsgPart A message part on which search operation has to be performed 
+for all the messages under a particular folder entry
+@param aQueryDesValue The corresponding value of the message part that needs to be searched 
+@param aRelOp  An enumeration corresponding to a relational operator used against a 
+particular message part for all the messages in a particular folder during 
+the search operation
+@return None
+@leave KErrNone - Query is added successfully to search-sort query
+
+KErrArgument - An invalid value is passed for a particular message part
+
+KErrMsvInvalidOperator - An invalid operation is being performed 
+on a particular message part 
+
+KErrMsvQueryMaxLimit - An addition of search-sort operation has lead to a condition 
+where the query options have exceeded the maximum number of search-sort options 
+supported by messaging framework. The maximum search options that can be added 
+to a search-sort query is ‘five’ and the maximum sort option that can be can be 
+added is ‘one’ 
+
+KErrQueryTooBig - The search-sort query is too big to be executed. 
+This could be due to a bigger value for the search-sort option provided as part of 
+the query. The query value added to a particular option is greater then KMsvMaxFindTextLength( = 300)
+*/
+EXPORT_C void CMsvSearchSortQuery::AddSearchOptionL (TMsvMessagePart aMsgPart, const TDesC& aQueryDesValue, TMsvRelationOp aRelOp)
+	{
+	//if query string is too big
+	if( aQueryDesValue.Length() >= KMsvMaxSearchTextLength)
+		{
+		User::Leave(KErrQueryTooBig);
+		}
+	
+	//if query string is empty
+	if( aQueryDesValue.Length() <= 0)
+		{
+		User::Leave(KErrArgument);
+		}
+		
+	//check whether it's reached maximum query limit
+	if(iQueryCount >= KMaxLevelOfSearchAndSort)
+		{
+		User::Leave(KErrMsvQueryMaxLimit);
+		}
+
+	// validate the query sent by client, before storing into the query structure.
+	User::LeaveIfError(ValidateQueryString(aMsgPart, aQueryDesValue, aRelOp));
+	
+	iIsSearchQuery = ETrue;
+	iQueryTable[iQueryCount].iQueryString.Copy(aQueryDesValue);
+	iQueryTable[iQueryCount].iMessagePart = aMsgPart;
+	iQueryTable[iQueryCount].iRelationOp = aRelOp;
+	iQueryCount++;
+	}
+
+/**
+Adds the search options to the search-sort query. 
+This function is used when the message part requires integer value during 
+search-sort operation
+
+@param aMsgPart A message part on which search operation has to be performed 
+for all the messages under a particular folder entry
+@param aQueryIntValue:  The corresponding value of the message part that needs to 
+be searched
+@param aRelOp An enumeration corresponding to a relational operator used against a 
+particular message part for all the messages in a particular folder during the 
+search operation 
+
+@return None
+@leave KErrNone - Query is added successfully to search-sort query
+
+KErrArgument - An invalid value is passed for a particular message part
+
+KErrMsvInvalidOperator - An invalid operation is being performed 
+on a particular message part 
+
+KErrMsvQueryMaxLimit - An addition of search-sort operation has lead to a condition 
+where the query options have exceeded the maximum number of search-sort options 
+supported by messaging framework. The maximum search options that can be added 
+to a search-sort query is ‘five’ and the maximum sort option that can be can be 
+added is ‘one’ 
+*/
+EXPORT_C void CMsvSearchSortQuery::AddSearchOptionL (TMsvMessagePart aMsgPart, const TInt  aQueryIntValue, TMsvRelationOp aRelOp)
+	{
+	//check whether it's reached maximum query limit
+	if(iQueryCount >= KMaxLevelOfSearchAndSort)
+		{
+		User::Leave(KErrMsvQueryMaxLimit);
+		}
+ 	
+	if((aMsgPart == EMsvPriority || aMsgPart == EMsvMtmTypeUID) && (aRelOp == EMsvEqual || aRelOp == EMsvNotEqual))
+		{
+		iIsSearchQuery = ETrue;
+		iQueryTable[iQueryCount].iQueryString.AppendNum(aQueryIntValue);
+		iQueryTable[iQueryCount].iMessagePart = aMsgPart;
+		iQueryTable[iQueryCount].iRelationOp = aRelOp;
+		iQueryCount++;
+		}
+	else if((aMsgPart == EMsvSize) && (aRelOp == EMsvEqual || aRelOp == EMsvNotEqual || aRelOp == EMsvLessThan || aRelOp == EMsvGreaterThan || aRelOp == EMsvLessThanOrEqual || aRelOp == EMsvGreaterThanOrEqual))
+		{
+		//validating size field.
+		if(aQueryIntValue <= 0)
+			{
+			User::Leave(KErrArgument);
+			}
+		//fill size info into query table	
+		iIsSearchQuery = ETrue;
+		iQueryTable[iQueryCount].iQueryString.AppendNum(aQueryIntValue);
+		iQueryTable[iQueryCount].iMessagePart = aMsgPart;
+		iQueryTable[iQueryCount].iRelationOp = aRelOp;
+		iQueryCount++;
+		}
+	else if((aMsgPart == EMsvAttachment ) && (aRelOp == EMsvEqual || aRelOp == EMsvNotEqual))
+		{
+		TInt attachmentValue = 0;
+		if(aQueryIntValue == 0)  //to search EMsvFile from CMsvAttachment
+			{
+			/*
+			* Internally assigning value 2 for EMsvFile, 3 for EMsvLinkedFile and 4 for EMsvMessageEntry
+			* because values 0 & 1 used to check whether EMsvAttachment present or not. 
+			*/
+			//for File attachment
+			attachmentValue = aQueryIntValue + 2;
+			}
+		else if(aQueryIntValue == 1) //to search EMsvLinkedFile from CMsvAttachment
+			{
+			//for Linked file attachment
+			attachmentValue = aQueryIntValue + 2;
+			}
+		else if(aQueryIntValue == 2) //to search EMsvMessageEntry from CMsvAttachment
+			{
+			//for Message entry attachment
+			attachmentValue = aQueryIntValue + 2;
+			}
+		else
+			{
+			User::Leave(KErrArgument);
+			}
+		//fill attachment info into query table	
+		iIsSearchQuery = ETrue;
+		iQueryTable[iQueryCount].iQueryString.AppendNum(attachmentValue);
+		iQueryTable[iQueryCount].iMessagePart = aMsgPart;
+		iQueryTable[iQueryCount].iRelationOp = aRelOp;
+		iQueryCount++;
+		}
+	else
+		{
+		User::Leave(KErrArgument);	
+		}
+	}
+	
+/**
+Adds the search options to the search-sort query. 
+This function is suitable when the message part value to be searched is a flag 
+or a message status.
+
+@param aMsgPart A message part on which search operation has to be performed 
+for all the messages under a particular folder entry
+@param aMessagePartFlagStatus:A Boolean value indicating if the flag indicated 
+by the message part is set or not
+@return None
+@leave KErrNone - Query is added successfully to search-sort query
+
+KErrArgument - An invalid value is passed for a particular message part
+
+KErrMsvInvalidOperator - An invalid operation is being performed 
+on a particular message part 
+
+KErrMsvQueryMaxLimit - An addition of search-sort operation has lead to a condition 
+where the query options have exceeded the maximum number of search-sort options 
+supported by messaging framework. The maximum search options that can be added 
+to a search-sort query is ‘five’ and the maximum sort option that can be can be 
+added is ‘one’ 
+*/
+
+EXPORT_C void CMsvSearchSortQuery::AddSearchOptionL (TMsvMessagePart aMsgPart, TBool aMessagePartFlagStatus)
+	{
+	//check whether it's reached maximum query limit
+	if(iQueryCount >= KMaxLevelOfSearchAndSort)
+		{
+		User::Leave(KErrMsvQueryMaxLimit);
+		}
+		
+	if(aMsgPart == EMsvNew || aMsgPart == EMsvUnreadMessages || aMsgPart == EMsvAttachment)
+		{
+		iIsSearchQuery = ETrue;
+		
+		iQueryTable[iQueryCount].iQueryString.AppendNum(aMessagePartFlagStatus);
+		iQueryTable[iQueryCount].iMessagePart = aMsgPart;
+		if(aMessagePartFlagStatus)
+			{
+			iQueryTable[iQueryCount].iRelationOp = EMsvEqual;
+			}
+		else
+			{
+			iQueryTable[iQueryCount].iRelationOp = EMsvNotEqual;	
+			}
+		iQueryCount++;
+		}
+	else
+		{
+		User::Leave(KErrArgument);	
+		}
+	}
+
+/**
+Adds sort options to the search-sort query, to enable sorting in ascending or 
+descending order based on the message part added to the query
+
+@param aMsgPart: A message part on which a sort operation is performed for all 
+the messages under a particular folder entry
+@param aSortOder: The sorting order in ascending or descending
+
+@return None
+@leave KErrNone - Query is added successfully to search-sort query
+KErrNotSupported - for multilevel sort
+*/
+
+EXPORT_C void CMsvSearchSortQuery::AddSortOptionL (TMsvMessagePart aMsgPart, TMsvSortOrder aSortOder)
+	{
+	if(aMsgPart == EMsvBody || iCountMultilevelSort >= 1)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	
+	if(aMsgPart < EMsvAttachment || aMsgPart > EMsvBody)
+		{
+		User::Leave(KErrArgument);
+		}
+				
+	if(iIsSearchQuery)
+		{
+		iExplicitSort = ETrue;
+		}
+	iSortOnMessagePart = aMsgPart;
+	iSortOrder = aSortOder;
+	iCountMultilevelSort++;
+	}
+
+
+/**
+Validate the query option sent by AddSearchOptionL ()
+@param aMsgPart Search needs to be on this TMessagePart
+@param aQueryString The text to be found. 
+@param aRelOp  TMsgRelationOp enum's needs to used along with TMessagePart to create the query string
+@return KErrNone or KErrArgument or KErrMsvInvalidOperator
+*/
+TInt CMsvSearchSortQuery::ValidateQueryString(TMsvMessagePart aMsgPart, const TDesC& aQueryString, TMsvRelationOp aRelOp)
+	{
+	// these messageparts should come with EMsvEqual relation operator
+	if((ValidateMessagePartAgainstEMsvEqualOperator(aMsgPart)) && aRelOp == EMsvEqual)
+		{
+		return KErrNone;
+		}
+	else if((aMsgPart == EMsvDate || aMsgPart == EMsvSize) && (ValidateMessagePartAgainstRelationOp(aRelOp)))
+		{
+		if(aMsgPart == EMsvDate)
+			{
+			//validating date field
+			//TTime(aQueryString);
+			TTime time;
+			TInt error = time.Set(aQueryString);
+			return error;
+			}
+		else
+			{
+			//validating size field.
+			TInt size;
+			TLex iLex(aQueryString);
+			iLex.Val(size);
+			if(size <= 0)
+				{
+				return KErrArgument ;
+				}
+			return KErrNone;	
+			}
+		}
+	else
+		{
+		return KErrArgument;
+		}
+	}
+
+
+/**
+get the message part from Query structure.
+@return TBool  ETrue or EFalse
+*/
+TMsvMessagePart CMsvSearchSortQuery::GetMessagePart(TInt aIndex)
+	{
+	return iQueryTable[aIndex].iMessagePart;	
+	}
+	
+/**
+get the sort field from the Query.
+@return TBool  ETrue or EFalse
+*/
+TMsvMessagePart CMsvSearchSortQuery::GetMessagePart()
+	{
+	return iSortOnMessagePart;	
+	}
+
+/**
+get the size of Query.
+@return TBool  ETrue or EFalse
+*/
+TInt CMsvSearchSortQuery::GetMaxQuerySize()
+	{
+	return iQueryCount;
+	}
+	
+
+/**
+Get Relation operator
+@return TSearchSortResultType  results as TMsvId or TMsvEntry
+*/
+TMsvRelationOp CMsvSearchSortQuery::GetRelationOp(TInt aIndex)
+	{
+	return iQueryTable[aIndex].iRelationOp;	
+	}
+
+/**
+Get search sort result type set by client.
+@return TSearchSortResultType  results as TMsvId or TMsvEntry
+*/
+TMsvSearchSortResultType CMsvSearchSortQuery::GetResultType ()
+	{
+	return iSearchSortResultType;
+	}
+
+
+/**
+Function to check whether whole word search enabled or not.
+@return ETrue or EFalse
+*/
+TBool CMsvSearchSortQuery::IsWholeWord()
+	{
+	return iWholeWord;
+	}
+	
+/**
+Function to check whether case sensitivesearch search enabled.
+@return ETrue or EFalse
+*/
+TBool CMsvSearchSortQuery::IsCaseSensitive()
+	{
+	return iCaseSensitive;
+	}
+
+/**
+Function to check whether wildcard character search enabled.
+@return ETrue or EFalse
+*/
+TBool CMsvSearchSortQuery::IsWildCardSearch()
+	{
+	return iWildCardCharacter;
+	}
+
+/**
+Function to check whether sub folder search enabled.
+@return ETrue or EFalse
+*/
+TBool CMsvSearchSortQuery::IsSubFolderSearch()
+	{
+	return iSubFolderSearch;
+	}
+
+/**
+Function to validate, is this search Query.
+@return TBool  ETrue or EFalse
+*/
+TBool CMsvSearchSortQuery::IsSearchQuery()
+	{
+	return iIsSearchQuery;
+	}
+
+//Validate TMsvMessagePart with EMsvEqual Operator
+TBool CMsvSearchSortQuery::ValidateMessagePartAgainstEMsvEqualOperator(TMsvMessagePart aMessagePart)
+	{
+	TBool validate = EFalse;
+	switch(aMessagePart)
+		{
+		case EMsvSubject:
+		case EMsvDetails:
+		case EMsvDescription:
+		case EMsvTo:
+		case EMsvFrom:
+		case EMsvCc:
+		case EMsvBcc:
+		case EMsvBody:
+			validate = ETrue;
+			break;
+		
+		default:
+			validate = EFalse;
+		}
+	
+	return validate;
+	}
+	
+//Validate TMsvMessagePart against TMsvRelationOp Operator
+TBool CMsvSearchSortQuery::ValidateMessagePartAgainstRelationOp(TMsvRelationOp aRelationOp)
+	{
+	TBool validate = EFalse;
+	switch(aRelationOp)
+		{
+		case EMsvEqual:
+		case EMsvNotEqual:
+		case EMsvLessThan:
+		case EMsvLessThanOrEqual:
+		case EMsvGreaterThan:
+		case EMsvGreaterThanOrEqual:
+			validate = ETrue;
+			break;
+		
+		default:
+			validate = EFalse;
+		}
+	
+	return validate;
+	}