--- /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<TUint32>& aIds) = 0;
+ virtual TInt FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<TUint32>& aRecordIds, RArray<TUint32>& 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<T>
+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<class TYPE>
+struct SMDBMetaElement
+ {
+ TMDBElementId iElementId;
+ TYPE iValue;
+ };
+
+/*
+Implementation of MMetaDBVisitor for a general type
+@internalComponent
+*/
+
+
+template <class TYPE>
+class TMDBVisitor : public TMDBVisitorBase
+/**
+Implementation of MMetaDBVisitor for a general element type
+@internalComponent
+*/
+ {
+public:
+
+ inline static TMDBVisitor<TYPE>* NewL(const TAny* aMem, const TAny* aData);
+ inline static TMDBVisitor<TYPE>* 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<TUint32>& aIds);
+ TInt FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<TYPE>* iTarget;
+
+protected:
+
+ TMDBVisitor(SMDBMetaElement<TYPE>* aData);
+ };
+
+
+
+template <class TYPE>
+inline TMDBVisitor<TYPE>::TMDBVisitor(SMDBMetaElement<TYPE>* aData)
+: TMDBVisitorBase(&(aData->iElementId)), iTarget(aData)
+/**
+ * Constructor
+ */
+ {
+ }
+
+
+
+template<class TYPE>
+inline TMDBVisitor<TYPE>* TMDBVisitor<TYPE>::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<TMDBVisitor<TYPE>*>( ::new ((TUint8*)aMem) TMDBVisitor( (SMDBMetaElement<TYPE>*)(aData) ) );
+ }
+
+template<class TYPE>
+inline TMDBVisitor<TYPE>* TMDBVisitor<TYPE>::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<TMDBVisitor<TYPE>*>( ::new ((TUint8*)aMem) TMDBVisitor( (SMDBMetaElement<TYPE>*)(((CMDBElement*)aData)->Data()) ) );
+ }
+
+
+template <class TYPE>
+inline TInt TMDBVisitor<TYPE>::Changed() const
+/*
+Has the value been changed by the caller?
+
+@internalComponent
+*/ {
+ if (iElementId)
+ {
+ return ( *iElementId & KCDChangedFlag );
+ }
+ return 0;
+ }
+
+
+template<class TYPE>
+inline void TMDBVisitor<TYPE>::ClearValue()
+ {
+ if (iTarget)
+ {
+ iTarget->iValue = 0;
+ SetFieldNull();
+ }
+ }
+
+
+template<>
+inline void TMDBVisitor<HBufC16*>::ClearValue()
+ {
+ if (iTarget)
+ {
+ delete iTarget->iValue;
+ iTarget->iValue = 0;
+ SetFieldNull();
+ }
+ }
+
+
+template<>
+inline void TMDBVisitor<HBufC8*>::ClearValue()
+ {
+ if (iTarget)
+ {
+ delete iTarget->iValue;
+ iTarget->iValue = 0;
+ SetFieldNull();
+ }
+ }
+
+
+template<class TYPE>
+inline TInt TMDBVisitor<TYPE>::RefreshL(CMDBSessionImpl* aSession)
+ {
+ return LoadL(aSession,*iElementId,*iElementId);
+ }
+
+
+template<class TYPE>
+inline TInt TMDBVisitor<TYPE>::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<TYPE> GetL() storage server Get returned err = %d for id %08x"), err, id);
+ User::Leave(err);
+ }
+ }
+ return err;
+ }
+
+
+
+template<>
+inline TInt TMDBVisitor<HBufC16*>::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<HBufC16*> GetL() storage server Get returned err = %d for id %08x"), err, id);
+ User::Leave(err);
+ }
+ }
+
+ return err;
+ }
+
+
+
+template<>
+inline TInt TMDBVisitor<HBufC8*>::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<HBufC8*> GetL() storage server Get returned err = %d for id %08x"), err, id);
+ User::Leave(err);
+ }
+ }
+
+ return err;
+ }
+
+
+
+template<class TYPE>
+inline TInt TMDBVisitor<TYPE>::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<TUint32> 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<TYPE> 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<TYPE> 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<class TYPE>
+inline TInt TMDBVisitor<TYPE>::LoadL(CMDBSessionImpl* aSession, TMDBElementId /*aRecordId*/, TMDBAttributeFlags /*aAttributeFlags*/,RArray<TUint32>& 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 <class TYPE>
+inline TInt TMDBVisitor<TYPE>::FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<TUint32> 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<TYPE> 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<TYPE> FindL() storage server FindL() did not find <%08x> masked with <%08x>"), ElementId(), mask);
+ err = KErrNotFound;
+ }
+ else
+ {
+ __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor<TYPE> 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<TYPE> 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<HBufC16*>::FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<HBufC16*> 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<TUint32> 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<TUint32> 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<HBufC16*> 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<HBufC16*> FindL() storage server FindL() did not find <%08x> masked with %08x"), ElementId(), mask);
+ err = KErrNotFound;
+ }
+ else
+ {
+ __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor<HBufC16*> 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<HBufC16*> 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<HBufC8*>::FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<TUint32> 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<HBufC8*> 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<HBufC8*> FindL() storage server FindL did not find <%08x> masked with <%08x>"), ElementId(), mask);
+ err = KErrNotFound;
+ }
+ else
+ {
+ __FLOG_STATIC3(KLogComponent, KCDErrLog, _L("TMDBVisitor<HBufC8*> 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<HBufC8*> 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<class TYPE>
+inline TInt TMDBVisitor<TYPE>::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<HBufC16*>::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<HBufC8*>::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<class TYPE>
+inline TInt TMDBVisitor<TYPE>::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<TUint32> 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<TYPE> 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<HBufC16*>::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<TUint32> 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<TYPE> 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<HBufC8*>::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<TUint32> 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<HBufC8*> 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<TUint32>& aIds);
+ TInt FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<CMDBRecordBase>* iTarget;
+
+protected:
+
+ TMDBRecordSetVisitor(RPointerArray<CMDBRecordBase>* aData);
+
+private:
+
+ void DoFindL(CMDBSessionImpl& aSession, CMDBElement& aElement, TInt& aErr, RArray<TUint32>& aCandidates, RArray<TUint32>& aMatches);
+ };
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Record Link Visitor
+//
+
+
+NONSHARABLE_CLASS(TMDBRecordLinkVisitor) : public TMDBVisitor<TInt>
+/*
+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<TUint32>& aIds);
+ TInt FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<TUint32>& aIds);
+ void FindTableL(CMDBSessionImpl& aSession, CMDBGenericRecord& aRealOwner, RArray<TUint32>& aMatchingIds);
+ TInt FindL(CMDBSessionImpl* aSession, RArray<TUint32>& 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<CMDBElement>* iTarget;
+
+protected:
+
+ TMDBGenericRecordVisitor(RPointerArray<CMDBElement>* aData);
+
+ TMDBVisitorBase* CreateVisitorL(TAny* mem, CMDBElement* element, SGenericRecordTypeInfo* aRecordInfo);
+
+private:
+
+ CMDBGenericRecord* SetReadyL();
+ };
+
+
+
+ } // End namespace CommsDat
+
+
+
+#endif //METADATABASEVISITOR_H