--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/client/src/mdequery.cpp Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,591 @@
+/*
+* Copyright (c) 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: Query base class
+*
+*/
+
+
+#include "mdequery.h"
+
+#include "mdeorderrule.h"
+#include "mdeinstanceitem.h"
+#include "mdelogiccondition.h"
+#include "mdenamespacedef.h"
+#include "mdepanic.h"
+
+
+CMdEQuery::CMdEQuery(TQueryType aType, CMdESession& aSession, CMdENamespaceDef& aNamespaceDef)
+ : iQueryId( 0 ), iSession(aSession), iNamespaceDef(aNamespaceDef), iType(aType),
+ iResultMode(EQueryResultModeItem), iState(EStateNew), iError(KErrNone),
+ iObjectResult(NULL), iCountResult(0), iDistinctResults(NULL)
+ {
+ }
+
+
+void CMdEQuery::QueryConstructL()
+ {
+ iConditions = CMdELogicCondition::NewL(ELogicConditionOperatorAnd);
+ }
+
+
+CMdEQuery::~CMdEQuery()
+ {
+ Cancel();
+
+ // This will destroy the entire conditions tree.
+ delete iConditions;
+
+ const TInt count = iResults.Count();
+
+ // Destroy all result items this query instance owns.
+ for(TInt i = 0; i < count; ++i)
+ {
+ if(iResults[i].iOwned)
+ {
+ delete iResults[i].iItem;
+ }
+ }
+
+ // Destroy object result item this query instance owns
+ if(iObjectResult.iItem)
+ {
+ if(iObjectResult.iOwned)
+ {
+ delete iObjectResult.iItem;
+ iObjectResult.iItem = NULL;
+ }
+ }
+
+ iCountResult = 0;
+
+ iResults.Reset();
+ iResults.Close();
+ iIdResults.Reset();
+ iIdResults.Close();
+
+ iOrderRules.Close();
+ iObservers.Close();
+
+ delete iDistinctResults;
+ }
+
+
+EXPORT_C TQueryType CMdEQuery::Type() const
+ {
+ return iType;
+ }
+
+EXPORT_C CMdENamespaceDef& CMdEQuery::NamespaceDef() const
+ {
+ return iNamespaceDef;
+ }
+
+EXPORT_C CMdESession& CMdEQuery::Session() const
+ {
+ return iSession;
+ }
+
+
+EXPORT_C CMdELogicCondition& CMdEQuery::Conditions() const
+ {
+ __ASSERT_DEBUG(iConditions ,
+ TMdEPanic::Panic(TMdEPanic::EInternal));
+ return *iConditions;
+ }
+
+
+EXPORT_C void CMdEQuery::AppendOrderRuleL(const TMdEOrderRule& aRule)
+ {
+ AssertInState(EStateNew);
+ iOrderRules.AppendL( aRule );
+ }
+
+
+EXPORT_C void CMdEQuery::InsertOrderRuleL(const TMdEOrderRule& aRule, TInt aPos)
+ {
+ AssertInState(EStateNew);
+ User::LeaveIfError( iOrderRules.Insert(aRule, aPos) );
+ }
+
+
+EXPORT_C TInt CMdEQuery::OrderRuleCount() const
+ {
+ return iOrderRules.Count();
+ }
+
+
+EXPORT_C void CMdEQuery::RemoveOrderRule(TInt aIndex)
+ {
+ AssertInState(EStateNew);
+ iOrderRules.Remove(aIndex);
+ }
+
+
+EXPORT_C TMdEOrderRule CMdEQuery::OrderRule(TInt aIndex) const
+ {
+ return iOrderRules[aIndex];
+ }
+
+
+EXPORT_C void CMdEQuery::FindL(TUint aMaxCount, TUint aNotifyCount)
+ {
+ AssertNotInState(EStateError);
+
+ // leave if query already running
+ if(iState == EStateSearching)
+ {
+ User::Leave(KErrNotReady);
+ }
+
+ const TInt count = iResults.Count();
+
+ // clear old results
+ // Destroy all result items this query instance owns.
+ for(TInt i = 0; i < count; ++i)
+ {
+ if(iResults[i].iOwned)
+ {
+ delete iResults[i].iItem;
+ }
+ }
+ iResults.Reset();
+
+ // Destroy object result item this query instance owns
+ if( iObjectResult.iItem )
+ {
+ if( iObjectResult.iOwned )
+ {
+ delete iObjectResult.iItem;
+ iObjectResult.iItem = NULL;
+ }
+ }
+
+ iIdResults.Reset();
+
+ if( iDistinctResults )
+ {
+ delete iDistinctResults;
+ iDistinctResults = NULL;
+ }
+
+ iCountResult = 0;
+ // end of clearing
+
+ DoFindL(aMaxCount, aNotifyCount);
+ }
+
+
+EXPORT_C void CMdEQuery::Cancel()
+ {
+ // is query incomplete before canceling
+ TBool incomplete = !IsComplete();
+
+ if( incomplete )
+ {
+ DoCancel();
+ }
+
+ if( iConditions )
+ {
+ iConditions->SetLocked( EFalse );
+ }
+
+ if( incomplete || IsComplete() == EFalse )
+ {
+ iState = EStateError;
+ NotifyCompleted( KErrCancel );
+ }
+ }
+
+
+EXPORT_C TBool CMdEQuery::IsComplete() const
+ {
+ return iState != EStateSearching ? ETrue : EFalse;
+ }
+
+
+EXPORT_C TInt CMdEQuery::Error() const
+ {
+ return iError;
+ }
+
+
+EXPORT_C TInt CMdEQuery::Count() const
+ {
+ if ( iResultMode == EQueryResultModeItem || iResultMode == EQueryResultModeObjectWithFreetexts )
+ {
+ return iResults.Count();
+ }
+ else if ( iResultMode == EQueryResultModeId )
+ {
+ return iIdResults.Count();
+ }
+ else if ( iResultMode == EQueryResultModeDistinctValues )
+ {
+ if( iDistinctResults )
+ {
+ return iDistinctResults->Count();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else // count query
+ {
+ return iCountResult;
+ }
+ }
+
+EXPORT_C CMdEItem& CMdEQuery::ResultItem(TInt aIndex) const
+ {
+ return *iResults[aIndex].iItem;
+ }
+
+
+EXPORT_C TItemId CMdEQuery::ResultId(TInt aIndex) const
+ {
+ return iIdResults[aIndex];
+ }
+
+EXPORT_C const RArray<TItemId>& CMdEQuery::ResultIds() const
+ {
+ return iIdResults;
+ }
+
+EXPORT_C CMdEItem* CMdEQuery::TakeOwnershipOfResult(TInt aIndex)
+ {
+ // Panic if an item is taken twice.
+ __ASSERT_DEBUG(iResults[aIndex].iOwned,
+ TMdEPanic::Panic(TMdEPanic::EQueryDoesntOwnResult));
+
+ // Applies only instance ownership
+ if ( iResultMode == EQueryResultModeItem || iResultMode == EQueryResultModeObjectWithFreetexts )
+ {
+ iResults[aIndex].iOwned = EFalse;
+ return static_cast<CMdEItem*>( iResults[aIndex].iItem );
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+
+
+EXPORT_C TBool CMdEQuery::OwnsResult(TInt aIndex)
+ {
+ return iResults[aIndex].iOwned;
+ }
+
+
+EXPORT_C CMdEQuery::TState CMdEQuery::State() const
+ {
+ return iState;
+ }
+
+void CMdEQuery::DoCancel()
+ {
+ SetState( EStateError );
+ }
+
+void CMdEQuery::SetState(TState aState)
+ {
+ if(aState == iState)
+ {
+ // Already in the specified state.
+ return;
+ }
+
+ // It's impossible to get out of the Error state.
+ AssertNotInState(EStateError);
+
+ // It's impossible to return to the New state.
+ __ASSERT_ALWAYS(aState > EStateFirst && aState < EStateLast &&
+ aState != EStateNew,
+ TMdEPanic::Panic(TMdEPanic::EInternal));
+
+ // Move out of the old state.
+ switch(iState)
+ {
+ case EStateNew:
+ // Moving out of the New state causes the search conditions to
+ // be locked.
+ iConditions->SetLocked();
+ break;
+
+ case EStateSearching:
+ // Searching has been completed.
+ break;
+
+ case EStateCompleted:
+ // Searching is been restarted.
+ break;
+
+ default:
+ break;
+ }
+
+ // Set the new state.
+ iState = aState;
+
+ // Move into the new state.
+ switch(iState)
+ {
+ case EStateSearching:
+ // Searching has been started.
+ break;
+
+ case EStateCompleted:
+ // Searching has been completed.
+ break;
+
+ case EStateError:
+ // The query has entered the Error state.
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+void CMdEQuery::AssertInState(TState aState)
+ {
+ __ASSERT_ALWAYS(aState == iState,
+ TMdEPanic::Panic(TMdEPanic::EQueryStateIllegalOperation));
+ }
+
+
+void CMdEQuery::AssertNotInState(TState aState)
+ {
+ __ASSERT_ALWAYS(aState != iState,
+ TMdEPanic::Panic(TMdEPanic::EQueryStateIllegalOperation));
+ }
+
+
+void CMdEQuery::NotifyNewResultsL(const RPointerArray<CMdEInstanceItem>& aNewResults)
+ {
+ __ASSERT_ALWAYS(iState != EStateNew && iState != EStateError,
+ TMdEPanic::Panic(TMdEPanic::EInternal));
+
+ TInt firstNewItemIndex = iResults.Count();
+ TInt i = 0;
+
+ // Query gets ownership of the results only if don't leave.
+ // If a leave occurs, the results array is restored to its original
+ // condition before any new results were added.
+
+ const TInt oldCount = iResults.Count();
+
+ TRAPD(err, AppendResultsL(aNewResults));
+ if (err != KErrNone)
+ {
+ // Cleanup: remove the ones that were added.
+ while (iResults.Count() > oldCount)
+ {
+ iResults.Remove(iResults.Count() - 1);
+ }
+ // Leave with the same error.
+ User::Leave(err);
+ }
+
+ // After this no leave can occur.
+
+ const TInt newCount = aNewResults.Count();
+
+ // Transfer ownership of the results to the query.
+ for (i = 0; i < newCount; i++)
+ {
+ iResults[firstNewItemIndex + i].iOwned = ETrue;
+ }
+
+ const TInt observerCount = iObservers.Count();
+
+ for (i = 0; i < observerCount; i++)
+ {
+ MMdEQueryObserver* observer = iObservers[i];
+ observer->HandleQueryNewResults( *this, firstNewItemIndex, newCount );
+ }
+ }
+
+
+void CMdEQuery::NotifyNewResultsL(const RArray<TItemId>& aNewResults)
+ {
+ __ASSERT_ALWAYS(iState != EStateNew && iState != EStateError,
+ TMdEPanic::Panic(TMdEPanic::EInternal));
+
+ TInt firstNewItemIndex = iIdResults.Count();
+ TInt i = 0;
+
+ const TInt oldCount = iIdResults.Count();
+
+ TRAPD(err, AppendResultsL(aNewResults));
+ if (err != KErrNone)
+ {
+ // Cleanup: remove the ones that were added.
+ while (iIdResults.Count() > oldCount)
+ {
+ iIdResults.Remove(iIdResults.Count() - 1);
+ }
+ // Leave with the same error.
+ User::Leave(err);
+ }
+
+ const TInt observerCount = iObservers.Count();
+
+ for (i = 0; i < observerCount; i++)
+ {
+ MMdEQueryObserver* observer = iObservers[i];
+ observer->HandleQueryNewResults(*this, firstNewItemIndex,
+ aNewResults.Count());
+ }
+ }
+
+void CMdEQuery::NotifyNewResultsL( const CDesCArray& aNewResults )
+ {
+ TInt firstNewItemIndex = aNewResults.Count();
+ TInt i = 0;
+
+ TInt oldCount = 0;
+ if( iDistinctResults )
+ {
+ oldCount = iDistinctResults->Count();
+ }
+ else
+ {
+ iDistinctResults = new (ELeave) CDesCArrayFlat( 8 );
+ }
+
+ TRAPD( err, AppendResultsL( aNewResults ) );
+ if( err != KErrNone )
+ {
+ // Cleanup: remove the ones that were added.
+ while( iDistinctResults->Count() > oldCount )
+ {
+ iDistinctResults->Delete( iDistinctResults->Count() - 1 );
+ }
+ // Leave with the same error.
+ User::Leave(err);
+ }
+
+ const TInt observerCount = iObservers.Count();
+
+ for (i = 0; i < observerCount; i++)
+ {
+ MMdEQueryObserver* observer = iObservers[i];
+ observer->HandleQueryNewResults( *this, firstNewItemIndex,
+ aNewResults.Count() );
+ }
+ }
+
+void CMdEQuery::NotifyNewResults(TUint32 aResult)
+ {
+ // Don't call observer here, since only one result
+ iCountResult = aResult;
+ }
+
+void CMdEQuery::AppendResultsL(const RPointerArray<CMdEInstanceItem>& aNewResults)
+ {
+ const TInt newResultCount = aNewResults.Count();
+ iResults.ReserveL( iResults.Count() + newResultCount );
+
+ for (TInt i = 0; i < newResultCount; ++i)
+ {
+ // At this point the ownership isn't transferred yet.
+ TResult result( aNewResults[i] );
+ iResults.AppendL( result );
+ }
+ }
+
+void CMdEQuery::AppendResultsL(const RArray<TItemId>& aNewResults)
+ {
+ const TInt newResultCount = aNewResults.Count();
+ iIdResults.ReserveL( iResults.Count() + newResultCount );
+
+ for (TInt i = 0; i < newResultCount; ++i)
+ {
+ // Add new results to query's list
+ iIdResults.AppendL( aNewResults[i] );
+ }
+ }
+
+void CMdEQuery::AppendResultsL( const CDesCArray& aNewResults )
+ {
+ const TInt count = aNewResults.Count();
+
+ for ( TInt i = 0; i < count; ++i )
+ {
+ iDistinctResults->AppendL( aNewResults[i] );
+ }
+ }
+
+void CMdEQuery::NotifyCompleted(TInt aError)
+ {
+ // The implementation must move out of the Searching state before
+ // notifying the base class.
+ __ASSERT_ALWAYS(iState != EStateSearching, TMdEPanic::Panic(TMdEPanic::EInternal));
+
+ // Update the latest error code.
+ iError = aError;
+ for (TInt i = iObservers.Count() - 1; i >= 0; --i)
+ {
+ MMdEQueryObserver* observer = iObservers[i];
+ observer->HandleQueryCompleted(*this, aError);
+ }
+ }
+
+
+EXPORT_C void CMdEQuery::AddObserverL(MMdEQueryObserver& aObserver)
+ {
+ __ASSERT_ALWAYS(iObservers.Find(&aObserver) == KErrNotFound,
+ TMdEPanic::Panic(TMdEPanic::EQueryDuplicateObserver));
+
+ iObservers.AppendL( &aObserver );
+ }
+
+
+EXPORT_C void CMdEQuery::RemoveObserver(MMdEQueryObserver& aObserver)
+ {
+ TInt index = iObservers.Find(&aObserver);
+
+ __ASSERT_ALWAYS(index != KErrNotFound,
+ TMdEPanic::Panic(TMdEPanic::EQueryUnknownObserver));
+
+ iObservers.Remove(index);
+ }
+
+
+EXPORT_C void CMdEQuery::SetResultMode( TQueryResultMode aMode )
+ {
+ iResultMode = aMode;
+ }
+
+EXPORT_C TQueryResultMode CMdEQuery::ResultMode() const
+ {
+ return iResultMode;
+ }
+EXPORT_C CMdEItem& CMdEQuery::ResultObjectItem() const
+ {
+ return *iObjectResult.iItem;
+ }
+
+EXPORT_C TPtrC16 CMdEQuery::ResultDistinctValue(TInt aIndex) const
+ {
+ return (*iDistinctResults)[aIndex];
+ }
+
+RArray<TMdEOrderRule>& CMdEQuery::OrderRules()
+ {
+ return iOrderRules;
+ }