diff -r 000000000000 -r dfb7c4ff071f commsfwtools/preparedefaultcommsdatabase/src/MetaDatabaseVisitor.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/commsfwtools/preparedefaultcommsdatabase/src/MetaDatabaseVisitor.h Thu Dec 17 09:22:25 2009 +0200 @@ -0,0 +1,1170 @@ +/** +* Copyright (c) 2004-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 MetaDatabaseVisitor.h + @internalComponent +*/ + +#if (!defined METADATABASEVISITOR_H) +#define METADATABASEVISITOR_H + + +namespace CommsDat +/* +Namespace encapsulates all types that are able to perform MMetaDatabase actions on specific record data types +*/ + { + +using namespace CommsDatInternal; +using namespace Meta; + + + +NONSHARABLE_CLASS(TMDBVisitorBase) : public Meta::MMetaType +/** +A general database visitor +@internalComponent +*/ + { +public: + + virtual ~TMDBVisitorBase(); + + ////////// From Meta::MMetaType ///////////////////////////////////////// + TInt Load(TPtrC8& aBuffer){ aBuffer == aBuffer; return 0; } + TInt Store(TDes8& aBuffer) const{aBuffer == aBuffer; return 0; } + void Copy(const TAny* aData) {aData = aData;} + TInt Length() const {return 0;} + /////////////////////////////////////////////////////////////////// + + // GET + virtual TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags) = 0; + virtual TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags, RArray& aIds) = 0; + virtual TInt FindL(CMDBSessionImpl* aSession, RArray& aIds) = 0; + virtual TInt RefreshL(CMDBSessionImpl* aSession) = 0; + virtual TInt GetL(CMDBSessionImpl* aSession); + + // SET + virtual TInt StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags) = 0; + virtual TInt ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags) = 0; + + virtual void SetOwner(CMDBElement* aOwner); + virtual TInt Changed() const = 0; + virtual void Sync(); + virtual void ClearValue(){} + +public: + + // These do not need to be specialised in inheriting templates + void Change(); + void FieldLoaded(); + TBool IsFieldLoaded(); + void SetFieldNull(); + + TUint32 TypeId(); + TUint32 ElementId(); + void SetElementId(TMDBElementId* aId); + void SetElementId(TMDBElementId aId); + + void SetMaxLength(TInt aLength); + + /* Removes all of the flags from the elementId of the DBVisitor - use only if the given record + * which needs to be loaded is NOT a template record!! Doesn't have to be virtual. + */ + void ResetElementId(TInt aRecId); + +protected: + + TMDBVisitorBase(TMDBElementId *aElementId); + TMDBVisitorBase(); + + void FindRecordsUsingTemplateL(CMDBSessionImpl* aSession, RArray& aRecordIds, RArray& aCandidateIds); + + TInt iMaxLength; + CMDBElement* iOwner; + + TMDBElementId* iElementId; + }; + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// TMDBVisitor +// +/** +Generic visitor for any simple MetaDatabase element. +Class is specialised to act on fields of type TMDBMetaField +where T is + TInt - (for any number - reals not used in comms database) + HBufC - for any string + HBufC8 - for binary data +*/ + + +/*Simple encapsulation of a metadatabase element for use by visitors +@internalComponent +*/ +template +struct SMDBMetaElement + { + TMDBElementId iElementId; + TYPE iValue; + }; + +/* +Implementation of MMetaDBVisitor for a general type +@internalComponent +*/ + + +template +class TMDBVisitor : public TMDBVisitorBase +/** +Implementation of MMetaDBVisitor for a general element type +@internalComponent +*/ + { +public: + + inline static TMDBVisitor* NewL(const TAny* aMem, const TAny* aData); + inline static TMDBVisitor* CreateL(const TAny* aMem, const TAny* aData); + + // GET + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags, RArray& aIds); + TInt FindL(CMDBSessionImpl* aSession, RArray& aIds); + TInt RefreshL(CMDBSessionImpl* aSession); + TInt GetL(CMDBSessionImpl* aSession); + + // SET + TInt StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags); + + TInt Changed() const; + //void SetOwner(CMDBElement* aOwner); + void ClearValue(); + +public: + + SMDBMetaElement* iTarget; + +protected: + + TMDBVisitor(SMDBMetaElement* aData); + }; + + + +template +inline TMDBVisitor::TMDBVisitor(SMDBMetaElement* aData) +: TMDBVisitorBase(&(aData->iElementId)), iTarget(aData) +/** + * Constructor + */ + { + } + + + +template +inline TMDBVisitor* TMDBVisitor::NewL(const TAny* aMem, const TAny* aData) +/** + * Instantiates a Visitor of a particular type. + * Used for attribute registration (in the data v-table). + */ + { + return static_cast*>( ::new ((TUint8*)aMem) TMDBVisitor( (SMDBMetaElement*)(aData) ) ); + } + +template +inline TMDBVisitor* TMDBVisitor::CreateL(const TAny* aMem, const TAny* aData) +/** + * Instantiates a Visitor of a particular type. + * Used for attribute registration (in the data v-table). + */ + { + return static_cast*>( ::new ((TUint8*)aMem) TMDBVisitor( (SMDBMetaElement*)(((CMDBElement*)aData)->Data()) ) ); + } + + +template +inline TInt TMDBVisitor::Changed() const +/* +Has the value been changed by the caller? + +@internalComponent +*/ { + if (iElementId) + { + return ( *iElementId & KCDChangedFlag ); + } + return 0; + } + + +template +inline void TMDBVisitor::ClearValue() + { + if (iTarget) + { + iTarget->iValue = 0; + SetFieldNull(); + } + } + + +template<> +inline void TMDBVisitor::ClearValue() + { + if (iTarget) + { + delete iTarget->iValue; + iTarget->iValue = 0; + SetFieldNull(); + } + } + + +template<> +inline void TMDBVisitor::ClearValue() + { + if (iTarget) + { + delete iTarget->iValue; + iTarget->iValue = 0; + SetFieldNull(); + } + } + + +template +inline TInt TMDBVisitor::RefreshL(CMDBSessionImpl* aSession) + { + return LoadL(aSession,*iElementId,*iElementId); + } + + +template +inline TInt TMDBVisitor::GetL(CMDBSessionImpl* aSession) +/* +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalComponent +*/ + { + if (! iTarget ) + { + User::Leave(KErrNotReady); + } + + TUint32 id = ElementId() & ~KCDMaskShowRes; + + TInt err = aSession->StorageL()->Get(id, iTarget->iValue); + + if(err == KErrNone) + { + FieldLoaded(); // value has been retrieved + } + else + { + Sync(); // indicates the field is still null. + + if (err != KErrNotFound && err != KErrPermissionDenied) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor GetL() storage server Get returned err = %d for id %08x"), err, id); + User::Leave(err); + } + } + return err; + } + + + +template<> +inline TInt TMDBVisitor::GetL(CMDBSessionImpl* aSession) +/* +Specialisation for HBufC16 +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalComponent +*/ + { + if (! iTarget ) + { + User::Leave(KErrNotReady); + } + + if( ! iTarget->iValue || + iTarget->iValue->Length() < iMaxLength) + { + delete iTarget->iValue; + iTarget->iValue = NULL; + iTarget->iValue = HBufC16::NewMaxL(iMaxLength); + } + + TPtr16 ptr = iTarget->iValue->Des(); + TUint32 id = ElementId() & KCDMaskHideRes; + + TInt err = aSession->StorageL()->Get(id, ptr); + + if(err == KErrNone) + { + FieldLoaded(); // value has been loaded + + HBufC16* temp = iTarget->iValue; + iTarget->iValue = HBufC16::NewMaxL(ptr.Length()); + TPtr16 ptrNew = iTarget->iValue->Des();; + ptrNew = ptr; + delete temp; + } + else + { + delete iTarget->iValue; + iTarget->iValue = NULL; + + Sync(); // indicates the field is null. + + if (err != KErrNotFound && err != KErrPermissionDenied) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor GetL() storage server Get returned err = %d for id %08x"), err, id); + User::Leave(err); + } + } + + return err; + } + + + +template<> +inline TInt TMDBVisitor::GetL(CMDBSessionImpl* aSession) +/* +Specialisation for HBufC8* +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalTechnology +*/ + { + if (! iTarget ) + { + User::Leave(KErrNotReady); + } + + if (! iTarget->iValue || + iTarget->iValue->Length() < iMaxLength) + { + delete iTarget->iValue; + iTarget->iValue = NULL; + iTarget->iValue = HBufC8::NewMaxL(iMaxLength); + } + + TPtr8 ptr = iTarget->iValue->Des(); + TUint32 id = ElementId() & KCDMaskHideRes; + + TInt err = aSession->StorageL()->Get(id, ptr); + + if(err == KErrNone) + { + FieldLoaded();// Value was retrieved + + /* + HBufC8* temp = iTarget->iValue; + iTarget->iValue = HBufC8::NewMaxL(ptr.Length()); + TPtr8 ptrNew = iTarget->iValue->Des();; + ptrNew = ptr; + delete temp; + */ + } + else + { + delete iTarget->iValue; + iTarget->iValue = NULL; + + Sync(); // indicates the field is null. + + if (err != KErrNotFound && err != KErrPermissionDenied) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor GetL() storage server Get returned err = %d for id %08x"), err, id); + User::Leave(err); + } + } + + return err; + } + + + +template +inline TInt TMDBVisitor::LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags /*aAttributeFlags*/) +/* +Assumes type and record id set by caller + +@internalComponent +*/ + { + if (! iTarget) + { + User::Leave(KErrNotReady); + } + + // set the element id to the full id set by the caller + iTarget->iElementId = (iTarget->iElementId & (KCDMaskShowType | KCDMaskShowRes)) | (aRecordId & KCDMaskShowRecordId); + + RArray ids; + CleanupClosePushL(ids); + + TUint32 mask = KCDMaskShowType | KCDMaskShowRecordId | aSession->GetReadAttributeMask(); + + TUint32 id = ElementId() & KCDMaskHideAttrAndRes; + + TInt err = (aSession->StorageL())->FindL(id, mask, ids); + + if ( err != KErrNone && err != KErrNotFound ) + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor LoadL() storage server FindL returned err = %d when looking for %08x, masked with %08x"), err, id, mask); + } +#ifdef __DEBUG + else if ( ids.Count() > 1 ) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor LoadL() storage server FindL/FindEqL %d fields found for %08x. Should be 1 or 0."), aIds.Count(), id & mask); + } +#endif + + // Load the field data + if (err == KErrNone) + { + // Set the full id + iTarget->iElementId = ids[0]; + err = GetL(aSession); + } + + CleanupStack::PopAndDestroy(&ids); + if ( err == KErrNotFound ) + { + // it's ok not to find a field. + // Don't report that error back. + // VCT - experimenting without this err = KErrNone; + } + + return err; + } + + + +template +inline TInt TMDBVisitor::LoadL(CMDBSessionImpl* aSession, TMDBElementId /*aRecordId*/, TMDBAttributeFlags /*aAttributeFlags*/,RArray& aIds ) +/* +Assumes type and record id set by caller + +@internalComponent +*/ + { + if (aIds.Count() == 0) + { + User::Leave(KErrNotFound); + } + + return LoadL(aSession, aIds[0] & KCDMaskShowRecordId, aIds[0] & KCDMaskShowAttributes); + } + + + +template +inline TInt TMDBVisitor::FindL(CMDBSessionImpl* aSession, RArray& aIds) +/* +Only find dont actually load +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalComponent +*/ + { + if (! iTarget ) + { + User::Leave(KErrNotReady); + } + + TInt err(KErrNotFound); + + // want to find this field in any record of this type that has appropriate attributes + // so mask out recordid, reserved bits and any attributes that need not be observed. + // TUint32 mask = KCDMaskShowType | (~aAttributeFlags & KCDMaskShowAttributes); + TUint32 mask = KCDMaskShowType | aSession->GetReadAttributeMask(); + + if (Changed()) + { + err = aSession->StorageL()->FindEqL(ElementId() & ~aSession->GetReadAttributeMask(), mask, iTarget->iValue, aIds); + + RArray ids; + CleanupClosePushL(ids); + + mask = (mask & ~ECDHidden) | KCDMaskShowRecordId; + + // Now look in template record to find other records + err = aSession->StorageL()->FindEqL(ElementId() & ~KCDMaskShowRecordId, mask, iTarget->iValue, ids); + + if ( err == KErrNone ) + { + FindRecordsUsingTemplateL(aSession, ids, aIds); + } + + if ( aIds.Count() ) + { + err = KErrNone; + } + + CleanupStack::PopAndDestroy(&ids); + } + else + { + err = aSession->StorageL()->FindL(ElementId() & ~aSession->GetReadAttributeMask(), mask, aIds); + } + + if ( aIds.Count() == 0) + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for %08x, masked with %08x"), err, ElementId(), mask); + if (err == KErrNone || err == KErrNotFound) + { + __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("TMDBVisitor FindL() storage server FindL() did not find <%08x> masked with <%08x>"), ElementId(), mask); + err = KErrNotFound; + } + else + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for <%08x>, masked with <%08x>"), err, ElementId(), mask); + } + } +#ifdef __DEBUG + else if ( aIds->Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL/FindEqL %d fields found for id %08x. Should be 1 or 0."), aIds.Count(), id & mask); + } +#endif + + return err; + } + + + +template <> +inline TInt TMDBVisitor::FindL(CMDBSessionImpl* aSession, RArray& aIds) +/* +Only find dont actually load +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalComponent +*/ + { + if (! iTarget || ! iTarget->iValue ) + { + User::Leave(KErrNotReady); + } + + // want to find this field in any record of this type that has appropriate attributes + // so mask out recordid, reserved bits and any attributes that need not be observed. + // TUint32 mask = KCDMaskShowType | (~aAttributeFlags & KCDMaskShowAttributes); + TUint32 mask = KCDMaskShowType | aSession->GetReadAttributeMask(); + + TInt err(KErrNotFound); + + if (Changed()) + { + const TDesC16& val = *iTarget->iValue; + // An absent text field is treated as being synonymous with one that is present but blank, ie + // searching for an empty descriptor matches both actual blanks and fields that aren't found. Because + // CenRep doesn't support such a thing we're forced to get handle this case by brute force: get the set + // of all record ids, fetch the desired field for each, and remove those records where the field is present + // and non blank. + if(val.Length() == 0) + { + // Get the set of all recordIds + TUint32 maskId = KCDMaskHideAttrAndRes & ~KCDColumnTypeInfo; + + TUint32 tableId = ElementId() | KCDMaskShowColumnTypeAndRecordId; + + err = (aSession->StorageL())->FindL(tableId, maskId, aIds); + + // remove node (side effect from query) + for (TInt idx = aIds.Count() - 1; idx >= 0; -- idx) + { + if( (aIds[idx] & ~KCDMaskShowAttrAndRes) == (tableId & ~KCDMaskShowAttrAndRes) ) + { + aIds.Remove(idx); + } + } + + if ( err != KErrNone && err != KErrNotFound ) + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for <%08x>, masked with <%08x>"), err, tableId, mask); + } + else + { + // Fetch the desired field for each record + RArray fieldIds; + CleanupClosePushL(fieldIds); + + TUint32 fieldId = (ElementId() & ~KCDMaskShowRecordId); + maskId = KCDMaskShowType | aSession->GetReadAttributeMask(); + + TInt errFieldSearch = aSession->StorageL()->FindL(fieldId, maskId, fieldIds); + if(errFieldSearch == KErrNone) + { + for(TInt fieldIdx = fieldIds.Count() - 1; fieldIdx >= 0; --fieldIdx) + { + for (TInt idx = aIds.Count() - 1; idx >= 0; -- idx) + { + // Remove those records where the field is present and non blank + if( (fieldIds[fieldIdx] & KCDMaskShowRecordId) == (aIds[idx] & KCDMaskShowRecordId )) + { + aIds.Remove(idx); + } + } + } + } + + CleanupStack::PopAndDestroy(&fieldIds); + } + } + else + { + if((ElementId() & KCDMaskHideRes) == KCDMaskGenericTableName) + { + mask = KCDMaskGenericTableName; + } + + err = aSession->StorageL()->FindEqL(ElementId() & ~aSession->GetReadAttributeMask(), mask, val, aIds); + + RArray ids; + CleanupClosePushL(ids); + + mask = (mask & ~ECDHidden) | KCDMaskShowRecordId; + + // Now look in template record + err = aSession->StorageL()->FindEqL(ElementId() & ~KCDMaskShowRecordId, mask, val, ids); + + if ( err == KErrNone ) + { + FindRecordsUsingTemplateL(aSession, ids, aIds); + } + + if ( aIds.Count() ) + { + err = KErrNone; + } + + CleanupStack::PopAndDestroy(&ids); + } + } + else + { + err = aSession->StorageL()->FindL(ElementId() & ~aSession->GetReadAttributeMask(), mask, aIds); + } + + if ( aIds.Count() == 0) + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for %08x, masked with %08x"), err, ElementId(), mask); + if (err == KErrNone || err == KErrNotFound) + { + __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("TMDBVisitor FindL() storage server FindL() did not find <%08x> masked with %08x"), ElementId(), mask); + err = KErrNotFound; + } + else + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL() returned err = %d when looking for <%08x>, masked with <%08x>"), err, ElementId(), mask); + } + } +#ifdef __DEBUG + else if ( aIds->Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL/FindEqL %d fields found for id. Should be 1 or 0."), aIds.Count(), ElementId() & mask); + } +#endif + + return err; + } + + + +template <> +inline TInt TMDBVisitor::FindL(CMDBSessionImpl* aSession, RArray& aIds) +/* +Only find dont actually load +Assumes fully resolved element Id but still needs mask for reserved bits + +@internalComponent +*/ + { + if (! iTarget || ! iTarget->iValue ) + { + User::Leave(KErrNotReady); + } + + // want to find this field in any record of this type that has appropriate attributes + // so mask out recordid, reserved bits and any attributes that need not be observed. + // TUint32 mask = KCDMaskShowType | (~aAttributeFlags & KCDMaskShowAttributes); + TUint32 mask = KCDMaskShowType | aSession->GetReadAttributeMask(); + + TInt err(KErrNotFound); + + if (Changed()) + { + const TDesC8& val = *iTarget->iValue; + // An absent text field is treated as being synonymous with one that is present but blank, ie + // searching for an empty descriptor matches both actual blanks and fields that aren't found. Because + // CenRep doesn't support such a thing we're forced to get handle this case by brute force: get the set + // of all record ids, fetch the desired field for each, and remove those records where the field is present + // and non blank. + // @TODO - find a cleaner way to achieve this + if(val.Length() == 0) + { + TUint32 recId = (ElementId() & ~KCDMaskShowFieldType) | KCDInitialColumnId; + err = aSession->StorageL()->FindL(recId & ~aSession->GetReadAttributeMask(), mask, aIds); + if(err == KErrNone) + { + TBuf8<1> dummyVal; // doesn't matter if it overflows; mere presence of non-blank is all we seek + for(TInt idx = aIds.Count() - 1; idx >= 0; --idx) + { + TUint32 fldId = (aIds[idx] & ~KCDMaskShowFieldType) | (ElementId() & KCDMaskShowFieldType); + TInt lookupErr = aSession->StorageL()->Get(fldId, dummyVal); + if(lookupErr == KErrOverflow || (lookupErr == KErrNone && dummyVal.Length() != 0)) + { + // comparison field does exist in this specific record but didn't match "" - remove + aIds.Remove(idx); + } + } + } + } + else + { + err = aSession->StorageL()->FindEqL(ElementId() & ~aSession->GetReadAttributeMask(), mask, val, aIds); + + RArray ids; + CleanupClosePushL(ids); + + mask = (mask & ~ECDHidden) | KCDMaskShowRecordId; + + // Now look in template record + err = aSession->StorageL()->FindEqL(ElementId() & ~KCDMaskShowRecordId, mask, val, ids); + + if ( err == KErrNone ) + { + FindRecordsUsingTemplateL(aSession, ids, aIds); + } + + if ( aIds.Count() ) + { + err = KErrNone; + } + + CleanupStack::PopAndDestroy(&ids); + } + } + else + { + err = aSession->StorageL()->FindL(ElementId() & ~aSession->GetReadAttributeMask(), mask, aIds); + } + + if ( aIds.Count() == 0) + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for %08x, masked with %08x"), err, ElementId(), mask); + if (err == KErrNone || err == KErrNotFound) + { + __FLOG_STATIC2(KLogComponent, KCDInfoLog, _L("TMDBVisitor FindL() storage server FindL did not find <%08x> masked with <%08x>"), ElementId(), mask); + err = KErrNotFound; + } + else + { + __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL returned err = %d when looking for <%08x>, masked with <%08x>"), err, ElementId(), mask); + } + } +#ifdef __DEBUG + else if ( aIds->Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor FindL() storage server FindL/FindEqL %d fields found when looking for <%08x>. Should be 1 or 0."), aIds.Count(), ElementId() & mask); + } +#endif + + return err; + } + + + +template +inline TInt TMDBVisitor::StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags) +/* + Store the field in the repository + + @internalComponent +*/ + { + if (! iTarget || ! iElementId ) + { + User::Leave(KErrNotReady); + } + + *iElementId = (*iElementId & ~KCDMaskShowRecordId) | (aRecordId & KCDMaskShowRecordId) | aAttributeFlags; + return aSession->StorageL()->Create( ElementId() & KCDMaskHideRes, iTarget->iValue); + } + + + +template<> +inline TInt TMDBVisitor::StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags) +/* + Store the field in the repository + + @internalComponent +*/ + { + if (! iTarget || ! iElementId ) + { + User::Leave(KErrNotReady); + } + + *iElementId = (*iElementId & ~KCDMaskShowRecordId) | (aRecordId & KCDMaskShowRecordId) | aAttributeFlags; + return aSession->StorageL()->Create( ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + + + +template<> +inline TInt TMDBVisitor::StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags) +/* + Store the field in the repository + + @internalComponent +*/ + { + if (! iTarget || ! iTarget->iValue ) + { + User::Leave(KErrNotReady); + } + + *iElementId = (*iElementId & ~KCDMaskShowRecordId) | (aRecordId & KCDMaskShowRecordId) | aAttributeFlags; + return aSession->StorageL()->Create( ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + + + +template +inline TInt TMDBVisitor::ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags) +/* +Modify the value of a field if the field exists +Never need to modify attributes as this is always done via the node. + +@internalComponent +*/ + { + TInt err(KErrNotFound); + + if (! iTarget || !iElementId ) + { + User::Leave(KErrNotReady); + } + + *iElementId |= aAttributeFlags; + + TUint32 mask = (KCDMaskShowType | KCDMaskShowRecordId); + + RArray ids; + CleanupClosePushL(ids); + + err = aSession->StorageL()->FindL(ElementId(), mask, ids); + + if (ids.Count() > 0) + { + +#ifdef __DEBUG + if (ids.Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor ModifyL() storage server FindL/FindEqL %d fields found when looking for id %08x. Should be 1 or 0."), aIds.Count(), ElementId() & mask); + } +#endif + + err = aSession->StorageL()->Set(ElementId() & KCDMaskHideRes, iTarget->iValue); + } + else + { + err = aSession->StorageL()->Create(ElementId() & KCDMaskHideRes, iTarget->iValue); + } + + CleanupStack::PopAndDestroy(&ids); + return err; + } + + + + +template<> +inline TInt TMDBVisitor::ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags) +/* +ElementId must be fully resolved before this call + +@internalComponent +*/ + { + if (! iTarget || !iElementId ) + { + User::Leave(KErrNotReady); + } + + *iElementId |= aAttributeFlags; + TUint32 mask = KCDMaskShowType | KCDMaskShowRecordId; + + RArray ids; + CleanupClosePushL(ids); + + TInt err = aSession->StorageL()->FindL(ElementId(), mask, ids); + + if (ids.Count() > 0) + { +#ifdef DEBUG + if (ids.Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor ModifyL() storage server FindL/FindEqL %d fields found when looking for id %08x. Should be 1 or 0."), aIds.Count(), ElementId() & mask); + } +#endif + + if(! iTarget->iValue) + { + return KErrNone; + } + + err = aSession->StorageL()->Set(ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + else + { + if(! iTarget->iValue) + { + return KErrNone; + } + err = aSession->StorageL()->Create(ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + + CleanupStack::PopAndDestroy(&ids); + return err; + } + + + +template<> +inline TInt TMDBVisitor::ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags) +/* +ElementId must be fully resolved before this call + +@internalComponent +*/ + { + if (! iTarget || !iElementId ) + { + User::Leave(KErrNotReady); + } + + *iElementId |= aAttributeFlags; + TUint32 mask = KCDMaskShowType | KCDMaskShowRecordId; + + RArray ids; + CleanupClosePushL(ids); + + TInt err = aSession->StorageL()->FindL(ElementId(), mask, ids); + + if (ids.Count() > 0) + { +#ifdef __DEBUG + if (ids.Count() > 1) + { + __FLOG_STATIC2(KLogComponent, KCDErrLog, _L("TMDBVisitor ModifyL() storage server FindL/FindEqL %d fields found when looking for %08x. Should be 1 or 0."), ids.Count(), ElementId() & mask); + } +#endif + + if(! iTarget->iValue) + { + return KErrNone; + } + + err = aSession->StorageL()->Set(ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + else + { + if(! iTarget->iValue) + { + return KErrNone; + } + + err = aSession->StorageL()->Create(ElementId() & KCDMaskHideRes, *(iTarget->iValue)); + } + + CleanupStack::PopAndDestroy(&ids); + return err; + } + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Record Set Visitor +// + +NONSHARABLE_CLASS(TMDBRecordSetVisitor) : public TMDBVisitorBase +/* +A visitor for CMDBRecordSet.data + +@internalComponent +*/ + { +public: + + static TMDBRecordSetVisitor* NewL(const TAny* aMem, const TAny* aData); + + // GET + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags, RArray& aIds); + TInt FindL(CMDBSessionImpl* aSession, RArray& aIds); + TInt RefreshL(CMDBSessionImpl* aSession); + + // SET + TInt StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags); + + TInt Changed() const; + void Sync(){} // do nothing - leave changed flag set + + //void SetOwner(CMDBElement* aOwner); + +public: + + RPointerArray* iTarget; + +protected: + + TMDBRecordSetVisitor(RPointerArray* aData); + +private: + + void DoFindL(CMDBSessionImpl& aSession, CMDBElement& aElement, TInt& aErr, RArray& aCandidates, RArray& aMatches); + }; + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Record Link Visitor +// + + +NONSHARABLE_CLASS(TMDBRecordLinkVisitor) : public TMDBVisitor +/* +A visitor for linked record data + +@internalComponent +*/ + { +public: + static TMDBRecordLinkVisitor* NewL(const TAny* aMem, const TAny* aData); + + // GET + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags, RArray& aIds); + TInt FindL(CMDBSessionImpl* aSession, RArray& aIds); + TInt RefreshL(CMDBSessionImpl* aSession); + TInt GetL(CMDBSessionImpl* aSession); + + // SET + TInt StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags); + + TInt Changed() const; + void SetOwner(CMDBElement* aOwner); + +private: + void SetLinkValueL(CMDBSession& aSession); + + void CheckLinkedRecordL(TMDBElementId aLinkedElementId); + + void CreateLinkedRecordL(CMDBSession& aSession, TMDBElementId aLinkedElementId); + + void CheckLinkValueL(TMDBElementId aLinkedElementId); + + void MaintainBCForLegacyLinks(); +public: + + CMDBElement** iLinkedRecord; + +protected: + + TMDBRecordLinkVisitor(CMDBElement** aData); + }; + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// User defined Record Visitor +// + + +NONSHARABLE_CLASS(TMDBGenericRecordVisitor) : public TMDBVisitorBase +/* +A visitor for data inside a user-defined record + +@internalComponent +*/ + { +public: + + static TMDBGenericRecordVisitor* NewL(const TAny* aMem, const TAny* aData); + + // GET + void LoadTableInfoL(CMDBSessionImpl& aSession, TMDBAttributeFlags aAttributeFlags, CMDBGenericRecord& aRealOwner); + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt LoadL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags, RArray& aIds); + void FindTableL(CMDBSessionImpl& aSession, CMDBGenericRecord& aRealOwner, RArray& aMatchingIds); + TInt FindL(CMDBSessionImpl* aSession, RArray& aIds); + TInt RefreshL(CMDBSessionImpl* aSession); + + // SET + void StoreTableInfoL(CMDBSessionImpl& aSession, CMDBGenericRecord& aRealOwner); + TInt StoreL(CMDBSessionImpl* aSession, TMDBElementId aRecordId, TMDBAttributeFlags aAttributeFlags); + TInt ModifyL(CMDBSessionImpl* aSession, TMDBAttributeFlags aAttributeFlags); + + TInt Changed() const; + void Sync(){} // do nothing - leave changed flag set + //void SetOwner(CMDBElement* aOwner); + +public: + + RPointerArray* iTarget; + +protected: + + TMDBGenericRecordVisitor(RPointerArray* aData); + + TMDBVisitorBase* CreateVisitorL(TAny* mem, CMDBElement* element, SGenericRecordTypeInfo* aRecordInfo); + +private: + + CMDBGenericRecord* SetReadyL(); + }; + + + + } // End namespace CommsDat + + + +#endif //METADATABASEVISITOR_H