upnpmediaserver/contentdirectoryservice/src/upnpcontentdirectorydb.cpp
changeset 0 7f85d04be362
child 25 52826dcbed74
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpmediaserver/contentdirectoryservice/src/upnpcontentdirectorydb.cpp	Thu Dec 17 08:52:00 2009 +0200
@@ -0,0 +1,1418 @@
+/** @file
+* Copyright (c) 2005-2006 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:  Database for MediaServer
+ *
+*/
+
+
+// INCLUDE FILES
+#include <barsread.h>
+#include <barsc.h>   
+#include <f32file.h>
+#include <xmlengdom.h>
+#include <sysutil.h>
+#include <upnpdominterface.h>
+#include <upnpstring.h>
+#include "upnpprotocolinfo.h"
+
+#include "upnpfileutils.h"
+#include "upnpcontentdirectorydb.h"
+#include "upnpcontentdirectoryglobals.h"
+#include "upnpelementfactory.h"
+#include "upnpelementbean.h"
+#include "upnpobjectbean.h"
+#include "upnpattributebean.h"
+#include "upnpfilterelement.h"
+#include "upnpresourcesbean.h"
+#include "upnpcdutils.h"
+#include "upnpcddbfactory.h"
+#include "upnpmetadatastorage.h"
+
+#define KLogFile _L("ContentDirectoryDb.log")
+#include "upnpcustomlog.h"
+
+// ============================= LOCAL FUNCTIONS ===============================
+// -----------------------------------------------------------------------------
+// CleanupFilterElementPointerArray
+// Used by TCleanupItem to clean a RPointerArray<CUpnpFilterElement>
+// -----------------------------------------------------------------------------
+//
+void CleanupFilterElementPointerArray( TAny* aArray )
+    {
+    (reinterpret_cast<RPointerArray<CUpnpFilterElement>*> (aArray))->ResetAndDestroy( );
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::CUpnpContentDirectoryDb
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CUpnpContentDirectoryDb::CUpnpContentDirectoryDb(
+    CUpnpMetadataStorage* aMetadataStorage )
+    {
+    iMetadataStorage =aMetadataStorage;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::ConstructL()
+    {
+    iDOMImpl.OpenL( );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::NewLC
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpContentDirectoryDb* CUpnpContentDirectoryDb::NewLC(
+    CUpnpMetadataStorage* aMetadataStorage )
+    {
+    CUpnpContentDirectoryDb* self = new ( ELeave ) CUpnpContentDirectoryDb(aMetadataStorage);
+    CleanupStack::PushL( self );
+    self->ConstructL( );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CUpnpContentDirectoryDb* CUpnpContentDirectoryDb::NewL(
+    CUpnpMetadataStorage* aMetadataStorage )
+    {
+    CUpnpContentDirectoryDb* self = NewLC( aMetadataStorage );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::~~CUpnpContentDirectoryDb
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CUpnpContentDirectoryDb::~CUpnpContentDirectoryDb()
+    {
+    iDOMImpl.Close( );
+    LOGCD( "CUpnpContentDirectoryDb::~CUpnpContentDirectoryDb", "", 0,
+        "DataBase closed" );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::InsertObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::InsertObjectL(
+    RXmlEngDocument& aFragment, TInt aContainerId, TInt* aId )
+    {
+    TUpnpErrorCode ret( EUpnpUndefined );
+    // get object element
+    TXmlEngElement element = UpnpCdUtils::GetObjectElementL( aFragment );
+
+    // start transaction
+    iMetadataStorage->BeginTransactionL( );
+
+    TRAPD( err, ret = DoInsertObjectL( element, aContainerId, aId ) );
+    if ( err )
+        { // rollback if error
+        iMetadataStorage->RollbackTransactionL( );
+        User::Leave( err );
+        }
+    iMetadataStorage->CommitTransactionL( );
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectListL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::GetObjectListL( TInt aParentId,
+    RArray<TInt>& aList )
+    {
+    return iMetadataStorage->GetObjectListL( aParentId, aList );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectListL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::GetObjectListL( const RArray<TInt>& aIds,
+    const TDesC8& aFilter, RArray<RXmlEngDocument>& aObjs )
+    {
+    for ( TInt i = 0; i < aIds.Count( ); i++ )
+        {
+        RXmlEngDocument obj;
+        CleanupClosePushL( obj );
+        GetObjectL( aIds[i], obj, aFilter );
+        aObjs.AppendL( obj );
+        CleanupStack::Pop( &obj );
+        }
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DeleteObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::DeleteObjectL( TInt aObjId,
+    RArray<TInt>& aRefList, TBool aDeleteResource )
+    {
+    return iMetadataStorage->DeleteObjectL( aObjId, aRefList, aDeleteResource );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::UpdateObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::UpdateObjectL( TInt aObjId,
+    RXmlEngDocument& aFragment )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+
+    // // get object element
+    TXmlEngElement element = UpnpCdUtils::GetObjectElementL( aFragment );
+
+    // start transaction
+    iMetadataStorage->BeginTransactionL( );
+
+    TRAPD( err, ret = DoUpdateObjectL( aObjId, element ) );
+    if ( err )
+        { // rollback - error
+        iMetadataStorage->RollbackTransactionL( );
+        User::Leave( err );
+        }
+    // commit if success
+    iMetadataStorage->CommitTransactionL( );
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DoUpdateObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::DoUpdateObjectL( TInt aObjId,
+    TXmlEngElement aFragment )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+
+    // delete object
+    ret = iMetadataStorage->DoDeleteObjectL( aObjId, EFalse, EFalse );
+    TXmlEngElement el = aFragment;
+    ret = InsertUpdatedL( aObjId, el );
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::InsertUpdatedL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::InsertUpdatedL( TInt aObjId,
+    TXmlEngElement& aElement )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+    iMetadataStorage->InsertObjectIntoObjectTableL( aElement );
+    ret = EUpnpOk;
+    RXmlEngNodeList<TXmlEngElement> elements;
+    CleanupClosePushL( elements );
+    aElement.GetChildElements( elements );
+
+    while ( elements.HasNext( ) )
+        {
+        TXmlEngElement el = elements.Next( );
+        if ( el.Name().CompareF( KClassTagName ) && el.Name().CompareF( KTitleTagName ) )
+            {
+            ret = InsertElementL( el, aObjId );
+            }
+        else
+            {
+            UpnpCdUtils::IsElementRequiredL( el ); // just remove the marker attr
+            }
+        }
+    CleanupStack::PopAndDestroy( &elements );
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::InsertElementL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::InsertElementL(
+    const TXmlEngElement& aElement, TInt aObjId )
+    {
+    return InsertAttributesL( aElement, iMetadataStorage->InsertElementL(
+        aElement, aObjId ), aObjId );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::PrepareDidlDocumentL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+RXmlEngDocument CUpnpContentDirectoryDb::PrepareDidlDocumentL()
+    {
+    RXmlEngDocument doc;
+    doc.OpenL( iDOMImpl );
+    TXmlEngElement el = doc.CreateDocumentElementL( KDidlLite( ) );
+    el.AddNamespaceDeclarationL( KXmlnsNsUri( ), KCmlnsNsPref( ) );
+    el.AddNamespaceDeclarationL( KDcNsUri( ), KDcNsPref( ) );
+    el.AddNamespaceDeclarationL( KUpnpNsUri( ), KUpnpNsPref( ) );
+    return doc;
+
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::CheckObjectRestrictionL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::CheckObjectRestrictionL( TInt aObjId )
+    {
+    return iMetadataStorage->CheckObjectRestrictionL( aObjId );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+TUpnpErrorCode CUpnpContentDirectoryDb::GetObjectL( TInt aObjectID,
+    RXmlEngDocument& aDoc, const TDesC8& aFilterString )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+
+    if ( aFilterString == KAsterisk8 )
+        { // get the whole object
+        ret = DoGetObjectL( aObjectID, aDoc, ETrue );
+        }
+    else if ( !aFilterString.Length( ) )
+        { // get only required properties
+        ret = DoGetObjectL( aObjectID, aDoc, EFalse );
+        }
+    else
+        {
+        RXmlEngDocument doc; // before the whole obj is created do not change the given reference,
+        CleanupClosePushL( doc ); // it prevents from returning not completed object if something goes wrong 
+        // during construction of response object
+        // get required properties
+        ret = DoGetObjectL( aObjectID, doc, EFalse );
+        if ( ret == EUpnpOk ) // do not not continue if something went wrong
+            {
+            // prepare a list of filter elements
+            RPointerArray<CUpnpFilterElement> filterElements;
+            TCleanupItem cleanupItem( CleanupFilterElementPointerArray,
+                &filterElements );
+            CleanupStack::PushL( cleanupItem );
+            // parse filter string
+            ParseFilterStringL( aFilterString, filterElements );
+            // add requested elements
+            AddRequestedPropertiesL( aObjectID,
+                UpnpCdUtils::GetObjectElementL( doc ), filterElements ); // ignore if error
+            //clean up
+            CleanupStack::PopAndDestroy( &filterElements );
+            }
+        if ( ret == EUpnpOk )
+            { // object is completed
+            aDoc = doc;
+            CleanupStack::Pop( &doc );
+            }
+        else
+            { // something went wrong
+            CleanupStack::PopAndDestroy( &doc );
+            }
+
+        }
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+TUpnpErrorCode CUpnpContentDirectoryDb::AddRequestedPropertiesL(
+    TInt aObjectID, TXmlEngElement aElement,
+    const RPointerArray<CUpnpFilterElement>& aFilterElements )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+    // aFilterElements must be sorted
+    for ( TInt i = 0; i < aFilterElements.Count( ); i++ )
+        {
+        const CUpnpFilterElement* filter = aFilterElements[i];
+        if ( filter->ElementName().Length( ) )
+            { // element part defined
+            AddElementL( aElement, aObjectID, filter );
+            }
+        else
+            { // element part not defined - it is attribute of main element tag
+            for ( TInt j = 0; j < filter->Count( ); j++ )
+                {
+                if ( (*filter)[j] == KChildCount )
+                    {
+                    SetChildCountL( aElement, aObjectID );
+                    ret = EUpnpOk;
+                    }
+                else
+                    {
+                    ret = iMetadataStorage->AddMainTagAttrL( aElement,
+                        aObjectID, (*filter)[j] );
+                    }
+                }
+            }
+        }
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::SetChildCountL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CUpnpContentDirectoryDb::SetChildCountL( TXmlEngElement aElement,
+    TInt aId )
+    {
+    if ( aElement.Name( ) == KContainer )
+        {
+        // value
+        TInt childCount = iMetadataStorage->GetChildCountL( aId );
+        TBuf8<KMaxIntegerLen> num;
+        num.Num( childCount );
+
+        // is it already exist?
+        TXmlEngAttr childAttr = aElement.AttributeNodeL( KChildCount( ) );
+        if ( childAttr.IsNull( ) )
+            { // not exist - add 
+            aElement.AddNewAttributeL( KChildCount( ), num );
+            }
+        else
+            { // already exists - update
+            childAttr.SetValueL( num );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::AddElementL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+void CUpnpContentDirectoryDb::AddElementL( TXmlEngElement aElement,
+    TInt aObjectID, const CUpnpFilterElement* aReqElement )
+    {
+    // get elements from database
+    RDbView view = iMetadataStorage->GetElementViewL( aObjectID,
+        aReqElement->ElementName( ) );
+    CleanupClosePushL( view );
+
+    // for each element found
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+        CUpnpElementBean* elBean = CUpnpElementBean::NewLC( view );
+
+        // add element
+        TXmlEngElement newElement = elBean->AttachElmL( aElement );
+
+        // add required attributes
+        AddAttributesL( elBean->ElmId( ), aObjectID, newElement, EFalse );
+
+        // for each requested attribute
+        for ( TInt i = 0; i < aReqElement->Count( ); i++ )
+            {
+            TPtrC8 attrNamePtr((*aReqElement)[i]);
+
+            TXmlEngAttr attr = newElement.AttributeNodeL( attrNamePtr );
+            // add if not present
+            // ignore if element has not any attribute
+            if ( attr.IsNull( ) && elBean->ElmHasAttribute( ) )
+                {
+                AddAttributeL( newElement, attrNamePtr, elBean->ElmId( ),
+                    aObjectID );
+                }
+            }
+        // clean up
+        CleanupStack::PopAndDestroy( elBean );
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::ParseFilterStringL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::ParseFilterStringL( const TDesC8& aFilter,
+    RPointerArray<CUpnpFilterElement>& aList )
+    {
+    // separate filter's parts
+    CDesC8ArrayFlat* list = new(ELeave) CDesC8ArrayFlat(KDefaultGranularity);
+    CleanupStack::PushL( list );
+    TInt commaPos;
+    TPtrC8 filter(aFilter);
+    while ( (commaPos = filter.Find( KCommaStr8( ) ) ) != KErrNotFound )
+        {
+        HBufC8* buf = filter.Left(commaPos).AllocLC( );
+        buf->Des().TrimAll( );
+        list->AppendL( *buf );
+        filter.Set( filter.Mid( commaPos+1 ) );
+        CleanupStack::PopAndDestroy( buf );
+        }
+    // add last
+    HBufC8* buf = filter.AllocLC( );
+    buf->Des().TrimAll( );
+    list->AppendL( *buf );
+    filter.Set( filter.Mid( commaPos+1 ) );
+    CleanupStack::PopAndDestroy( buf );
+
+    // sort to simplify
+    list->Sort( );
+
+    TPtrC8 curr( KMinusOne8 );
+    for ( TInt i = 0; i< list->Count( ); i++ ) // for each filter property
+        {
+        // split filter string - element@attribute
+        TInt atPos = (*list)[i].Find( KAtStr8 );
+        TPtrC8 attr;
+        if ( atPos == KErrNotFound ) // is it element name
+            { // it is element
+            attr.Set( KNullDesC8 );
+            atPos = (*list)[i].Length( );
+            }
+        else
+            {
+            attr.Set( (*list)[i].Mid( atPos+1 ) );
+            }
+        TPtrC8 element((*list)[i].Left( atPos ) );
+
+        // do not add "class" and "title" elements - required by default
+        if ( element.CompareF( KClassTagNameWithNs8 )
+                && element.CompareF( KTitleTagNameWithNs8 ) )
+            { // it is neither a class nor title element
+            if ( element == curr )
+                { // already exists, add next attribute
+                if ( attr.Length( ) ) // ignore empty attr
+                    aList[aList.Count()-1]->AppendAttributeL( attr );
+                }
+            else
+                { // create new filter element
+                CUpnpFilterElement* tmp = CUpnpFilterElement::NewLC( );
+                tmp->SetElementNameL( element );
+                if ( attr.Length( ) ) // ignore epmty attr
+                    tmp->AppendAttributeL( attr );
+                aList.AppendL( tmp );
+                CleanupStack::Pop( tmp );
+                curr.Set( element );
+                }
+            }
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( list );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DoGetObjectL
+// Function returns DIDL-Lite XML fragment with metadata for requested object.
+// IMPORTANT: 1. Caller takes responsibility for returned document and is 
+//              obliged to close it.
+//           2. The root element of the document is <DIDL-Lite> element and
+//              the object's element is its direct, onluy child.
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::DoGetObjectL( TInt aObjectID,
+    RXmlEngDocument& aDoc, TBool aAll )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+    RDbView view = iMetadataStorage->GetObjViewL( aObjectID );
+    CleanupClosePushL( view );
+
+    // Get result
+    if ( view.FirstL( ) )
+        {
+        // get row
+        view.GetL( );
+
+        // prepare DIDL-Lite
+        RXmlEngDocument doc;
+        CleanupClosePushL( doc );
+        doc = PrepareDidlDocumentL( );
+
+        // object bean      
+        CUpnpObjectBean* objBean = CUpnpObjectBean::NewLC( view );
+        TXmlEngElement objElement;
+
+        if ( aAll )
+            { // all object's properties
+            objElement
+                    = objBean->AttachWholeObjectElL( doc.DocumentElement( ) );
+            // childCount
+            SetChildCountL( UpnpCdUtils::GetObjectElementL( doc ),
+                objBean->ObjId( ) );
+            }
+        else
+            { // only required
+            objElement = objBean->AttachObjectElL( doc.DocumentElement( ) );
+            }
+
+        // clean up
+        CleanupStack::PopAndDestroy( objBean );
+
+        // aObjectID might be a reference object, so trying to get real object id        
+        TInt realObjectId = ReferedObjectIdL( aObjectID );
+
+        // add elements to the tree
+        AddElementsL( realObjectId, objElement, aAll );
+
+        // assign to the given reference
+        aDoc = doc;
+        // everything went right
+        ret = EUpnpOk;
+        // do not remove doc
+        CleanupStack::Pop( &doc );
+        }
+    else
+        { // the is no such object
+        ret = ENoSuchObject;
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::AddElementsL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::AddElementsL( TInt aObjectID,
+    TXmlEngElement aObjectElement, TBool aAll )
+    {
+    RDbView view = iMetadataStorage->GetElementsViewL( aObjectID, aAll );
+    CleanupClosePushL( view );
+    // Iterate through elements
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+        CUpnpElementBean* elBean = CUpnpElementBean::NewLC( view );
+
+        // add new element
+        TXmlEngElement newElement = elBean->AttachElmL( aObjectElement );
+
+        // add attributes
+        AddAttributesL( elBean->ElmId( ), aObjectID, newElement, aAll );
+
+        // clean up
+        CleanupStack::PopAndDestroy( elBean );
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::AddAttributesL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//  
+void CUpnpContentDirectoryDb::AddAttributesL( TInt aElementId,
+    TInt aObjectID, TXmlEngElement& aElement, TBool aAll )
+    {
+    RDbView view = iMetadataStorage->GetAttributesViewByObjectIdL( aObjectID,
+        aAll );
+    CleanupClosePushL( view );
+
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt elmIdColNo = colSet->ColNo( KAtrElmIdColName );
+    delete colSet;
+
+    // Iterate through attributes
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+
+        if ( view.ColInt( elmIdColNo ) == aElementId )
+            {
+            CUpnpAttributeBean* atr = CUpnpAttributeBean::NewLC( view );
+            atr->AttachAttrL( aElement );
+            CleanupStack::PopAndDestroy( atr );
+            }
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DoInsertObjectL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::DoInsertObjectL(
+    TXmlEngElement& aElement, TInt aContainerId, TInt* aId )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+
+    *aId = SetObjectIdL( aElement );
+    UpnpCdUtils::SetContainerIdL( aElement, aContainerId );
+    iMetadataStorage->InsertObjectIntoObjectTableL( aElement );
+    ret = EUpnpOk;
+    RXmlEngNodeList<TXmlEngElement> elements;
+    CleanupClosePushL( elements );
+    aElement.GetChildElements( elements );
+
+    while ( elements.HasNext( ) )
+        {
+        TXmlEngElement el = elements.Next( );
+        if ( el.Name().CompareF( KClassTagName ) && el.Name().CompareF( KTitleTagName ) )
+            {
+            ret = InsertElementL( el, *aId );
+            }
+        else
+            {
+            UpnpCdUtils::IsElementRequiredL( el ); // just remove the marker attr
+            }
+        }
+    // set object childCount
+    SetChildCountL( aElement, *aId );
+
+    CleanupStack::PopAndDestroy( &elements );
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::InsertAttributesL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::InsertAttributesL(
+    const TXmlEngElement aElement, TInt aElmId, TInt aObjId )
+    {
+    TUpnpErrorCode ret = EUpnpUndefined;
+    RXmlEngNodeList<TXmlEngAttr> list;
+    CleanupClosePushL( list );
+    aElement.GetAttributes( list );
+    if ( list.Count( ) )
+        {
+        RArray<TXmlEngAttr> attributes; // to store real attr
+        CleanupClosePushL( attributes );
+        RArray<TXmlEngAttr> markers; // to store marker attr
+        CleanupClosePushL( markers );
+        // separate markers from attr
+        while ( list.HasNext( ) )
+            {
+            TXmlEngAttr attr = list.Next( );
+            if ( attr.Name().Match( KRequiredAtrSufPattern ) == KErrNotFound )
+                {
+                attributes.AppendL( attr );
+                }
+            else
+                {
+                markers.AppendL( attr );
+                }
+            }
+
+        // insert attributes
+        for ( TInt i = 0; i < attributes.Count( ); i++ )
+            {
+            iMetadataStorage->InsertAttributeL( attributes[i], aElmId,
+                IsAttrRequiredL( attributes[i], markers ), aObjId );
+            ret = EUpnpOk;
+            }
+        // remove markers from DOM tree
+        for ( TInt i = 0; i < markers.Count( ); i++ )
+            {
+            markers[i].Remove( );
+            }
+        // clean up
+        CleanupStack::PopAndDestroy( &markers );
+        CleanupStack::PopAndDestroy( &attributes );
+        }
+    else
+        {
+        ret = EUpnpOk;
+        }
+
+    CleanupStack::PopAndDestroy( &list );
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::IsAttrRequiredL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpContentDirectoryDb::IsAttrRequiredL( const TXmlEngAttr& aAttr,
+    RArray<TXmlEngAttr>& aMarkers )
+    {
+    TBool ret = EFalse;
+
+    for ( TInt i = 0; i< aMarkers.Count( ); i++ )
+        {
+        if ( aMarkers[i].Name().Find( aAttr.Name( ) ) == 0 )
+            { // attr required
+            ret = ETrue;
+            break;
+            }
+        }
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::SetObjectIdL
+// Sets the id val in the objected to be created
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::SetObjectIdL( TXmlEngElement& aElement )
+    {
+    TInt ret = iMetadataStorage->GetNextKeyL( KObjectTableName8 );
+    UpnpCdUtils::SetObjectIdL( aElement, ret );
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectIdL
+// Gets the id val in the objected to be created
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetObjectIdL()
+    {
+    TInt ret = iMetadataStorage->NextKeyL( KObjectTableName8 );
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectIdL
+// Gets the id val in the objected to be created
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+HBufC8* CUpnpContentDirectoryDb::GetObjectTitleL( TInt aId )
+    {
+    return iMetadataStorage->GetObjectTitleL( aId );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::ReferedObjectIdL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::ReferedObjectIdL( TInt aObjectId )
+    {
+    TInt ret = KErrNotFound;
+
+    TInt refId = iMetadataStorage->ReferedObjectIdL( aObjectId );
+
+    if ( refId != KErrNotFound )
+        {
+        ret = ReferedObjectIdL( refId );
+        }
+    else
+        {
+        ret = aObjectId;
+        }
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetElIdByAttrL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetObjIdByAttrL( const TDesC8& aAttrName,
+    const TDesC8& aAttrVal )
+    {
+    TInt objId = KErrNotFound;
+
+    TInt elmId = iMetadataStorage->GetElmIdForAttrL( aAttrName, aAttrVal );
+    if ( elmId != KErrNotFound )
+        {
+        objId = iMetadataStorage->GetObjIdForElmIdL( elmId );
+        }
+
+    return objId;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjIdByAttrLikeL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetObjIdByAttrLikeL( const TDesC8& aAttrName,
+    const TDesC8& aAttrVal )
+    {
+    TInt objId = KErrNotFound;
+
+    TInt elmId = iMetadataStorage->GetElmIdForAttrLikeL( aAttrName, aAttrVal );
+    if ( elmId != KErrNotFound )
+        {
+        objId = iMetadataStorage->GetObjIdForElmIdL( elmId );
+        }
+
+    return objId;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectByAttrL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::GetObjectByAttrL(
+    RXmlEngDocument& aDoc, TInt* aObjId, const TDesC8& aAttrName,
+    const TDesC8& aAttrVal )
+    {
+    TUpnpErrorCode ret = EUndefined;
+
+    *aObjId = GetObjIdByAttrL( aAttrName, aAttrVal );
+    if ( *aObjId >= 0 )
+        {
+        ret = GetObjectL( *aObjId, aDoc, KAsterisk8 );
+        }
+    else
+        { // something went wrong
+        ret = ENoSuchObject;
+        }
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::CheckParentRestrictionL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TUpnpErrorCode CUpnpContentDirectoryDb::CheckParentRestrictionL( TInt aObjId )
+    {
+    return iMetadataStorage->CheckParentRestrictionL( aObjId );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DeleteResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::DeleteResourceL( const TDesC8& aResVal,
+    RArray<TInt>& aContIds )
+    {
+    // start transaction
+    iMetadataStorage->BeginTransactionL( );
+
+    TRAPD( err, DoDeleteResourceL( aResVal, aContIds ) );
+    if ( err != KErrNone )
+        { // rollback - error
+        iMetadataStorage->RollbackTransactionL( );
+        User::Leave( err );
+        }
+    // commit if success
+    iMetadataStorage->CommitTransactionL( );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DoDeleteResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::DoDeleteResourceL( const TDesC8& aResVal,
+    RArray<TInt>& aContIds )
+    {
+    HBufC* resVal = HBufC::NewLC( aResVal.Length( ) );
+    resVal->Des().Copy( aResVal );
+
+    HBufC* resValReplaced16 = UpnpCdUtils::EscapeAposL( *resVal );
+    CleanupStack::PushL( resValReplaced16 );
+    HBufC8* resValReplaced8 = UpnpCdUtils::DesToDes8LC( *resValReplaced16 );
+    RArray<TInt> objs;
+    CleanupClosePushL( objs );
+    GetObjectsByResourceL( objs, *resValReplaced16 );
+
+    // not any obj?
+    if ( !objs.Count( ) )
+        {
+        User::Leave( ENoSourceResource );
+        }
+
+    TUpnpErrorCode err = EUpnpOk;
+
+    // for each object
+    for ( TInt i = 0; i < objs.Count( ); i++ )
+        {
+        CUpnpObjectBean* objBn = GetObjBeanLC( objs[i] );
+        if ( !objBn->ObjRestricted( ) )
+            {
+            if ( CheckObjectRestrictionL( objBn->ObjParentId( ) ) == EUpnpOk )
+                {
+                iMetadataStorage->DeleteResElL( *resValReplaced16,
+                    objBn->ObjId( ) );
+                aContIds.AppendL( objBn->ObjParentId( ) );
+                }
+            else
+                {
+                err = ERestrictedParentObject;
+                }
+            }
+        else
+            {
+            err = ERestrictedObject;
+            }
+        CleanupStack::PopAndDestroy( objBn );
+        }
+
+    // was any deleted
+    if ( !aContIds.Count( ) )
+        {
+        User::Leave( err );
+        }
+
+    // if each deleted?
+    if ( aContIds.Count( ) == objs.Count( ) )
+        {
+        // try to fetch resource id
+        TRAPD( err, UpnpCdUtils::ResIdFromUriL( *resValReplaced8 ) );
+        // ignore if error - resource id could not be fetched
+        if ( !err )
+            { // OK
+            // delete resource
+            DeleteResourceByResIdL( UpnpCdUtils::ResIdFromUriL( *resValReplaced8 ) );
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &objs );
+    CleanupStack::PopAndDestroy( resValReplaced8 );
+    CleanupStack::PopAndDestroy( resValReplaced16 );
+    CleanupStack::PopAndDestroy( resVal );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjBeanLC
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CUpnpObjectBean* CUpnpContentDirectoryDb::GetObjBeanLC( TInt aObjId )
+    {
+    CUpnpObjectBean* objBn = 0;
+
+    RDbView view = iMetadataStorage->GetObjViewL( aObjId );
+    CleanupClosePushL( view );
+
+    if ( view.FirstL( ) )
+        {
+        // get values
+        view.GetL( );
+        objBn = CUpnpObjectBean::NewL( view );
+        }
+
+    // clean up 
+    CleanupStack::PopAndDestroy( &view );
+
+    CleanupStack::PushL( objBn );
+    return objBn;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectIdsL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::GetObjectsByResourceL( RArray<TInt>& aIds,
+    const TDesC& aResVal )
+    {
+
+    RDbView view = iMetadataStorage->GetViewOfObjectListForResL( aResVal );
+    CleanupClosePushL( view );
+
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt colNo = colSet->ColNo( KElmObjIdColName );
+    delete colSet;
+
+    // for each row
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+        TInt no = view.ColInt( colNo );
+        aIds.AppendL( no );
+        }
+
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetProtocolInfoL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetProtocolInfoL( const TDesC8& aContentUri,
+    CUpnpDlnaProtocolInfo*& aProtocolInfo )
+    {
+    HBufC* uri = HBufC::NewLC( aContentUri.Length( ) );
+    TPtr uriPtr(uri->Des( ));
+    uriPtr.Copy( aContentUri );
+    TInt ret = GetElmIdByNameAndValL( KRes16, uriPtr );
+    if ( ret >= 0 )
+        {
+        HBufC8* attrVal;
+        GetAttrValueByNameL( ret, KprotocolInfo, attrVal );
+        CleanupStack::PushL( attrVal );
+        aProtocolInfo = CUpnpDlnaProtocolInfo::NewL( *attrVal );
+        CleanupStack::PopAndDestroy( attrVal );
+        }
+    CleanupStack::PopAndDestroy( uri );
+
+    if ( ret >= 0 ) //item ID number is't meaningfull for function caller
+        {
+        ret = KErrNone;
+        }
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetElmIdByNameAndValL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetElmIdByNameAndValL( const TDesC& aElmName,
+    const TDesC& aElmValue )
+    {
+    TInt ret = KErrNotFound;
+
+    RDbView view = iMetadataStorage->GetViewOfElmIdByNameAndValL( aElmName,
+        aElmValue );
+    CleanupClosePushL( view );
+
+    // col id
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt colNo = colSet->ColNo( KElmIdColName );
+    delete colSet;
+
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+        ret = view.ColInt( colNo );
+        }
+
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+
+    return ret;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetAttrValueByNameL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+
+HBufC8* CUpnpContentDirectoryDb::GetProtocolInfoByImportUriL(
+    const TDesC8& aImportUri )
+    {
+    CUpnpAttributeBean* attBean =
+            GetAttrByValueL( KImportUri8( ), aImportUri );
+    CleanupStack::PushL( attBean );
+
+    HBufC8* attValBuf = NULL;
+    if ( attBean )
+        {
+        //KprotocolInfo
+        CUpnpAttributeBean* att = GetAttrByNameL( attBean->AtrElmId( ),
+            KprotocolInfo( ), attValBuf );
+        delete att;
+        }
+    CleanupStack::PopAndDestroy( attBean );
+    return attValBuf;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetAttrValueByNameL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::GetAttrValueByNameL( TInt aElmId,
+    const TDesC8& aAttrName, HBufC8*& aAttrVal )
+    {
+    CUpnpAttributeBean* atrBean =
+            GetAttrByNameL( aElmId, aAttrName, aAttrVal );
+    delete atrBean;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetAttrByValueL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CUpnpAttributeBean* CUpnpContentDirectoryDb::GetAttrByValueL(
+    const TDesC8& aAttrName, const TDesC8& aAttrVal )
+    {
+    RDbView view = iMetadataStorage->GetAttrViewL( aAttrName, aAttrVal );
+    CleanupClosePushL( view );
+
+    TInt number = view.CountL( );
+
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt colNo = colSet->ColNo( KAtrValueColName );
+    delete colSet;
+
+    CUpnpAttributeBean* atrBean = NULL;
+    if ( view.FirstL( ) )
+        {
+        view.GetL( );
+        atrBean = CUpnpAttributeBean::NewLC( view );
+        CleanupStack::Pop( atrBean );
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    return atrBean;
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetAttrByNameL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CUpnpAttributeBean* CUpnpContentDirectoryDb::GetAttrByNameL( TInt aElmId,
+    const TDesC8& aAttrName, HBufC8*& aAttrVal )
+    {
+    RDbView view = iMetadataStorage->GetAttrViewL( aElmId, aAttrName );
+    CleanupClosePushL( view );
+
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt colNo = colSet->ColNo( KAtrValueColName );
+    delete colSet;
+
+    CUpnpAttributeBean* atrBean = NULL;
+    if ( view.FirstL( ) )
+        {
+        view.GetL( );
+        atrBean = CUpnpAttributeBean::NewLC( view );
+        aAttrVal = atrBean->AtrValue().AllocL( );
+        CleanupStack::Pop( atrBean );
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    return atrBean;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetObjectIdByElementValueLikeL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetObjectIdByElementValueLikeL(
+    const TDesC8& aElmName, const TDesC8& aElmValue )
+    {
+    // convert to unicode
+    HBufC* elmName = UpnpCdUtils::Des8ToDesLC( aElmName );
+    HBufC* elmValue = UpnpCdUtils::Des8ToDesLC( aElmValue );
+
+    // prepare query buf
+    HBufC* query = HBufC::NewLC( KSelectFromSqlCmd().Length( ) + KElmObjIdColName().Length( ) + KElementTableName().Length( ) + KElmNameColName().Length( ) + elmName->Length( ) + KAndLikeConditionSqlCmd().Length( ) + KElmValueColName().Length( ) + elmValue->Length( ) );
+
+    TPtr queryPtr(query->Des( ));
+
+    // format query
+    queryPtr.Format( KSelectFromSqlCmd, &KElmObjIdColName,
+        &KElementTableName, &KElmNameColName, elmName );
+    queryPtr.AppendFormat( KAndLikeConditionSqlCmd, &KElmValueColName,
+        elmValue );
+
+    // prepare
+    RDbView view = iMetadataStorage->GetEvaluatedViewL( queryPtr );
+    CleanupClosePushL( view );
+
+    // col no
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt colNo = colSet->ColNo( KElmObjIdColName );
+    delete colSet;
+
+    TInt ret = KErrNotFound;
+
+    // for one row
+    if ( view.NextL( ) )
+        {
+        view.GetL( );
+        if ( !view.IsColNull( colNo ) )
+            {
+            ret = view.ColInt( colNo );
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &view );
+    CleanupStack::PopAndDestroy( query );
+
+    CleanupStack::PopAndDestroy( elmValue );
+    CleanupStack::PopAndDestroy( elmName );
+
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetParentIdL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetParentIdL( TInt aObjectId )
+    {
+    return iMetadataStorage->GetParentIdL( aObjectId );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::AddAttributeL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+
+void CUpnpContentDirectoryDb::AddAttributeL( TXmlEngElement aElement,
+    const TDesC8& aAttrName, TInt aElementId, TInt aObjectId )
+    {
+    RDbView view = iMetadataStorage->GetAttrViewByObjectIdL( aObjectId,
+        aAttrName );
+    CleanupClosePushL( view );
+
+    CDbColSet* colSet = view.ColSetL( );
+    const TInt elmIdColNo = colSet->ColNo( KAtrElmIdColName );
+    delete colSet;
+
+    // Iterate through attributes - usually there is only one
+    while ( view.NextL( ) )
+        {
+        view.GetL( );
+
+        if ( view.ColInt( elmIdColNo ) == aElementId )
+            {
+            CUpnpAttributeBean* atr = CUpnpAttributeBean::NewLC( view );
+            atr->AttachAttrL( aElement );
+            CleanupStack::PopAndDestroy( atr );
+            }
+        }
+
+    // clean up
+    CleanupStack::PopAndDestroy( &view );
+    }
+// -----------------------------------------------------------------------------
+// CContentDirectoryDb::CanBeNestedL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpContentDirectoryDb::CanBeNestedL( TInt aObjId )
+    {
+    // get path
+    HBufC8* path = iMetadataStorage->GetObjectPathL( aObjId );
+    CleanupStack::PushL( path );
+
+    // count levels
+    TPtrC8 rest(path->Des( ));
+    TInt levelNo(1); // root level
+    TInt pos( KErrNotFound );
+    while ( (pos = rest.Find( KPathSeparator8 )) != KErrNotFound )
+        {
+        rest.Set( rest.Mid( pos + KPathSeparator8().Length( ) ) );
+        levelNo++;
+        }
+    // clean up
+    CleanupStack::PopAndDestroy( path );
+    return (levelNo < KAvailableNestedLevels);
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::AddResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::AddResourceL( CUpnpResourcesBean* aResBean,
+    TInt aObjId )
+    {
+    iMetadataStorage->AddResourceL( aResBean, aObjId );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DeleteResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::DeleteResourceByResIdL( TInt64 aResId,
+    TBool aDeleteFile )
+    {
+    iMetadataStorage->DeleteResourceByResIdL( aResId, aDeleteFile );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::DeleteResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::DeleteResourceByObjIdL( TInt aObjId,
+    TBool aDeleteFile )
+    {
+    iMetadataStorage->DeleteResourceByObjIdL( aObjId, aDeleteFile );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetResourceL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CUpnpResourcesBean* CUpnpContentDirectoryDb::GetResourceL( TInt64 aResId )
+    {
+    return iMetadataStorage->GetResourceL( aResId );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::ResNewDownloadDirectoryL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::NewMediaDirectoryL( const TDesC& aOldDir )
+    {
+    //UPDATE resources SET rsc_readonly=1 WHERE KRscPathColName LIKE $aOldDir* AND KRscReadonlyColName=0
+    // prepare command
+    HBufC* query = HBufC::NewLC( KNewMediaDirSqlCmd().Length( ) + aOldDir.Length( ) );
+    TPtr SqlCmd(query->Des( ));
+    SqlCmd.Format( KNewMediaDirSqlCmd, &aOldDir );
+
+    // execute
+    iMetadataStorage->ExecuteL( SqlCmd );
+
+    CleanupStack::PopAndDestroy( query );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::GetKeyForUriL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::GetKeyForUriL()
+    {
+    return iMetadataStorage->GetNextKeyL( KImportUriId8 );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::CheckDatabaseL
+// -----------------------------------------------------------------------------
+//
+void CUpnpContentDirectoryDb::CheckDatabaseL()
+    {
+    iMetadataStorage->CheckDatabaseL( );
+    }
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::RecreateDatabaseFile
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::RecreateDatabaseFile()
+    {
+    TRAPD( err, iMetadataStorage->RecreateDatabaseFileL( ) );
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::HandleDbError
+// -----------------------------------------------------------------------------
+//
+TInt CUpnpContentDirectoryDb::HandleDbError( TInt aError )
+    {
+    return iMetadataStorage->HandleDbError( aError );
+    }
+
+// -----------------------------------------------------------------------------
+// CUpnpContentDirectoryDb::IsDbCreated
+// -----------------------------------------------------------------------------
+//
+TBool CUpnpContentDirectoryDb::IsDbCreated()
+    {
+    return iMetadataStorage->IsDbCreated( );
+    }
+
+//  End of File